Uygulamanızı prefetch_related
ile hızlandırmaya çalışıyoruz. GenericForeignKey
ilişkilerini izleyebilir ve __
ile daha derine gidebilir ancak maalesef ilgili modelde böyle bir alan yoksa başarısız olur. İşte Aynı DB sütuna ait birden çok alan
class ModelA(models.Model):
event_object = models.ForeignKey(SomeModelA)
class ModelB(models.Model):
event = models.ForeignKey(SomeModelB)
class ModelC(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
Yani ModelC
örneği ModelA
veya ModelB
ya işaret edebilir modeli yapının bazı örnektir. Ve ben hem A ve B modellerini önceden getirmek için böyle Sorgu Kümesi kullanabilirsiniz: ModelC.objects.all().prefetch_related('content_object')
Maalesef ben de olay nesneyi seçmek gerekir (SomeModelA
veya SomeModelB
)
Ben
ModelC.objects.all().prefetch_related('content_object', 'content_object__event_object')
İşe yarayacak çalıştırmayı denerseniz eğer ModelA
işaret sadece ModelC
örneklerini var, ama ModelB
event_object
alanı var ve bunun yerine event
yok çünkü DİĞER ÖN durumda, başarısız olur.
Bu modeller, kod genelinde birçok yerde kullanılır, böylece alanı yeniden adlandırmak iyi bir fikir değildir. Bu yüzden bir alan/sütun için bir takma ad oluşturmanın bir yolu olup olmadığını merak ediyorum.
böyle yapmaya çalıştığım:
class ModelB(models.Model):
event = models.ForeignKey(SomeModelB)
event_object = models.ForeignKey(SomeModelB, db_column='event_id', related_name='+')
DB tablosundaki aynı sütuna işaret iki alan yapmak için. Ancak bu, save
yöntemini kırdığı için çalışmıyor. Django, bir sütunun iki kez yerleştirildiği ve bir DatabaseError
Aldığı UPDATE
SQL sorgusu oluşturur Bu takma ad oluşturmanın bir yolu var mı? Ya da belki bir istisna atmamak için prefetch_related
yapmak için başka bir çözüm var mı?
Güncelleme: save
yöntemde bu alanı dışlamak için kullanılabilecek bir update_fields
parametre vardır. Ancak 1.5’te tanıtıldı ve 1.4 kullanıyoruz. Bu yüzden bir cevap aramaya devam ediyorum.
Güncelleştirme # 2: @ shx2 bana bir traceback vermemi istedi. 2 olası geri dönüş var. 1 - nitelik birinci nesne üzerinde eksik olduğunda:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 72, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 97, in __iter__
len(self)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 89, in __len__
self._prefetch_related_objects()
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 570, in _prefetch_related_objects
prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1664, in prefetch_related_objects
(attr, first_obj.__class__.__name__, lookup))
AttributeError: Cannot find 'event_object' on ModelB object, 'content_object__event_object' is an invalid parameter to prefetch_related()
Ve prefetch_related parametreler daha sonra ilk nesne için geçerli olup olmadığını ben 2 Traceback olsun
:Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 72, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 97, in __iter__
len(self)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 89, in __len__
self._prefetch_related_objects()
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 570, in _prefetch_related_objects
prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1680, in prefetch_related_objects
obj_list, additional_prl = prefetch_one_level(obj_list, prefetcher, attr)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1803, in prefetch_one_level
qs = getattr(obj, attname).all()
AttributeError: 'ModelB' object has no attribute 'event_object'
'prefetch_related' hatasının izini ekleyebilirsiniz. – shx2
Neden bir ModelC queryset'e ihtiyacınız var? Sadece 2 farklı sorgu yapabilir ve ayrı ayrı tedavi edemez misiniz? Benim sorumun biraz naif olduğunu biliyorum, ama bazen sorun şu ki bu zorluklarla yüz yüze geldiğimiz için – marianobianchi
@marianobianchi no, django yöneticisinin bir kısmını optimize etmeye çalışıyoruz, bu yüzden tek bir sorgulamaya ihtiyacımız var. Ayrıca yukarıdaki modeller basitleştirilmiş, gerçek proje – Igor