2016-04-04 14 views
0

select_related veya prefetch_related kullanarak ilgili bir nesnenin önceden getirilip getirilmediğini kontrol etmek istiyorum, böylece verileri buna göre serileştirebilirim. İşte bir örnek: Bu örnekteİlgili bir nesnenin önceden getirilip getirilmediğini kontrol etmenin bir yolu var mı?

class Address(models.Model): 
    street = models.CharField(max_length=100) 
    zip = models.CharField(max_length=10) 

class Person(models.Model): 
    name = models.CharField(max_length=20) 
    address = models.ForeignKey(Address) 

def serialize_address(address): 
    return { 
     "id": address.id, 
     "street": address.street, 
     "zip": address.zip 
    } 

def serialize_person(person): 
    result = { 
     "id": person.id, 
     "name": person.name 
    } 
    if is_fetched(person.address): 
     result["address"] = serialize_address(person.address) 
    else: 
     result["address"] = None 

###### 

person_a = Person.objects.select_related("address").get(id=1) 
person_b = Person.objects.get(id=2) 

serialize_person(person_a) #should be object with id, name and address 
serialize_person(person_b) #should be object with only id and name 

, fonksiyon is_fetched aradığım şeydir. Kişi nesnesinin zaten bir çözüm adresine sahip olup olmadığını ve sadece sahip olduğu takdirde, bunun seri hale getirilip getirilmediğini belirlemek istiyorum. Fakat eğer olmazsa, başka bir veritabanı sorgusu yürütülmemelidir.

Django'da bunu başarmanın bir yolu var mı?

cevap

3

address ilişkisi getirildiyse, Kişi nesnesinin _address_cache adlı doldurulmuş bir özniteliği olur; Bunu kontrol edebilirsin.

def is_fetched(obj, relation_name): 
    cache_name = '_{}_cache'.format(relation_name) 
    return getattr(obj, cache_name, False) 

Not nesne ve ilişkinin adı ile bu çağırmak gerekir: person.address yapıyor hemen getir tetikleyecek

is_fetched(person, 'address') 

beri. Düzenle Düzeltme veya çoktan çoğa ilişkisi yalnızca prefetch_related; Bu, anahtarın ilgili modelin adı olduğu listelerin bir listesi olan _prefetched_objects_cache tek bir özniteliği doldurur. Örneğin bunu yaparsanız:

addresses = Address.objects.prefetch_related('person_set') 

sonra addresses her öğenin bir "person' anahtarını içeren bir _prefetched_objects_cache dicti sahip olacaktır.

Not: Bunların her ikisi de, özel API'nin bir parçası oldukları anlamına gelen tek alt çizgi nitelikleridir; Bunları kullanmakta özgürsünüz, ancak Django da bunları gelecek sürümlerde değiştirmek için ücretsizdir.

+0

Teşekkürler, bu umut verici görünüyor. Ayrıca ManyToMany ilişkileri veya ters ForeignKey ilişkileri için çalışacak mı? Örneğin: '_topping_set_cache'? – basilikum

İlgili konular