想象一下,我有两个简单的模型(它不是我所拥有的,但这样做):
Class Person(models.Model):
person_id = models.TextField()
name = models.TextField()
#...some other fields
Class Pet(models.Model):
person_id = models.TextField()
pet_name = models.TextField()
species = models.TextField()
#...even more fields
以下是此示例与我读到的其他一些问题之间的主要区别:我的模型不执行外键,因此我无法使用select_related()
我需要创建一个视图,显示每个查询集之间的连接。所以,让我们想象一下,我想要一个名叫约翰的所有人带着一只狗的视图。
# a first filter
person_query = Person.objects.filter(name__startswith="John")
# a second filter
pet_query = Pet.objects.filter(species="Dog")
# the sum of the two
magic_join_that_i_cant_find_and_posibbly_doesnt_exist = join(person_query.person_id, pet_query.person_id)
现在,我可以将这两个非常简单的查询集与任何函数一起加入吗?
或者我应该使用原始的?
SELECT p.person_id, p.name, a.pet_name, a.species
FROM person p
LEFT JOIN pet a ON
p.person_id = a.person_id AND
a.species = 'Dog' AND
p.name LIKE 'John%'
此查询可以吗?该死的,我不确定......这是我的疑问问题。一切都是一次性的。但连续的查询似乎很简单......
如果我在我的模型类中引用一个"外键" (对于select_related()
使用),是否会在迁移后在数据库中强制执行? (我需要它发生的事情)
答案 0 :(得分:2)
制作模型。使用外键,但使用db_constraint=False
。
请参见https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey.db_constraint
此外,如果此模型为managed=False
,即它是旧版数据库表,并且您没有使用Django迁移,则永远不会进行约束,这很好。
答案 1 :(得分:1)
如果在模型中创建FK,Django将在迁移时创建约束,因此您希望在您的情况下避免这种情况。
如果你没有声明要加入外键的字段,我认为没有办法在Django中加入数据库。你唯一能做的就是在Python中进行连接,这可能是也可能没有。认为prefetch_related
正是这样做的。
代码如下:
person_query = Person.objects.filter(name__startswith="John")
person_ids = [person.id for person in person_query]
pet_query = Pet.objects.filter(species="Dog", person_id__in=person_ids).order_by('person_id')
pets_by_person_id = {person_id: pet_group for person_id, pet_group in itertools.groupby(pet_query, lambda pet: pet.person_id)}
# Now everytime you need the pets for a certain person
pets_by_person_id(person.id)
# You can also set it in all objects for easy retrieval
for person in person_query:
person.pets = pets_by_person_id(person.id)
代码可能不是100%准确,但你会得到我希望的想法。