gpt4 book ai didi

python - Django 无法确定以一对一关系链接一对多的查询集

转载 作者:太空狗 更新时间:2023-10-30 00:58:53 26 4
gpt4 key购买 nike

我有一个系统,其中与一个模型存在多对一关系(例如 1 a -> 多个 b),并且许多模型与另一个模型存在一对一关系(例如 1 b -> 1 c) ).画成这样:

  /--- b1 --- c1
/
a ---- b2 --- c2
\
\--- b3 --- c3

我决心创建一个方法,收集与 a 对应的所有 c

给定一个与我的结构相同的模型系统,我能想到的最好方法显示在方法中:Person.find_important_treats()

有没有更好的方法不涉及对数据库的如此多的调用?

from django.db import models

class Person(models.Model):
""" The 'a' from my above example """

def find_important_treats(self):
return (pet.treat for pet in self.pets)

class Pet(models.Model):
""" The 'b' from my above example """

owner = models.ForeignKey(
to=Person,
related_name='pets'
)

favourite_treat = models.ForeignKey(
to=Treat,
)

class Treat(models.Model):
""" The 'c' from my above example """
pass

最佳答案

我建议根据您的用例使用两种几乎相似的解决方案:

  • 使用缓存
    class Person(models.Model): 
""" The 'a' from my above example """

@property
def iter_important_treats(self):
return (pet.treat_id for pet in self.pets.all()) # will use the cached objects if they exist

person = Person.objects.get(id=person_id).select_related('pets') # to cache the pets list within the person object avoiding future additional queries
treats = Treat.objects.filter(id__in=person.iter_importent_treats)
  • 不使用缓存:
class Person(models.Model): 
""" The 'a' from my above example """

@property
def iter_important_treats(self):
return iter(self.pets.values_list('treat_id', flat=True)) # caching will not affect the query behviour

person = Person.objects.get(id=person_id)
treats = Treat.objects.filter(id__in=person.iter_importent_treats)

注意:

  1. 我们使用 treat_id 而不是 treat__id 来避免额外的连接查询,因为 django 已经在 Pet 对象级别保存了 treat_id 但如果你使用 treat__id 然后强制执行连接查询。
  2. 将属性限制为 ID 的迭代器只是为了可逆性和可维护性

关于python - Django 无法确定以一对一关系链接一对多的查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47804372/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com