[英]Django: select_related and GenericRelation
select_related是否適用於GenericRelation關系,還是有合理的替代方案? 目前Django正在為我的查詢集中的每個項目執行單獨的sql調用,並且我想避免使用像select_related這樣的東西。
class Claim(models.Model):
proof = generic.GenericRelation(Proof)
class Proof(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
我正在選擇一堆聲明,我希望將相關的Proofs拉入而不是單獨查詢。
沒有內置的方法來做到這一點。 但我發布了一種在我的博客上模擬一般關系上的 select_related
的技術。
博客內容匯總:
我們可以使用Django的_content_object_cache
字段來創建我們自己的select_related
用於泛型關系。
generics = {}
for item in queryset:
generics.setdefault(item.content_type_id, set()).add(item.object_id)
content_types = ContentType.objects.in_bulk(generics.keys())
relations = {}
for ct, fk_list in generics.items():
ct_model = content_types[ct].model_class()
relations[ct] = ct_model.objects.in_bulk(list(fk_list))
for item in queryset:
setattr(item, '_content_object_cache',
relations[item.content_type_id][item.object_id])
在這里,我們獲取查詢集中關系使用的所有不同內容類型,以及每個內容的不同對象ID的集合,然后使用內置的in_bulk管理器方法一次性獲取所有內容類型 - 使用ID鍵入的字典。 然后,我們為每個內容類型執行一次查詢,再次使用in_bulk,以獲取所有實際對象。
最后,我們只需將相關對象設置為源項的_content_object_cache字段即可。 我們這樣做的原因是,如果您直接調用x.content_object,這是Django將檢查的屬性,並在必要時填充。 通過預先填充它,我們確保Django永遠不需要調用單獨的查找 - 實際上我們正在做的是為泛型關系實現一種select_related()。
看起來像select_related和GRs不能一起工作 。 我想你可以為Claim寫一些訪問器,通過相同的查詢獲取它們。 這篇文章為您提供了一些關於原始SQL的指針 ,以便在需要時獲取通用對象
您可以使用.extra()函數手動提取字段:
Claims.filter(proof__filteryouwant=valueyouwant).extra(select={'field_to_pull':'proof_proof.field_to_pull'})
.filter()將執行連接,.extra()將提取字段。 proof_proof是Proof模型的SQL表名。 如果您需要多個字段,請在字典中指定每個字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.