django查询过滤器选择相关

use*_*979 2 django django-queryset

这里的人是从请求返回的人物对象

PersonAddressBook.objects.select_related().get(person = person).client
Run Code Online (Sandbox Code Playgroud)

上面的代码返回客户端对象如何重写它以返回多个客户端.一个人对象可能在多个personaddressbook中所以过滤而不是get是我想要做但我想要客户端对象而不使用for-loop

其他模型看起来如何

class Client:
    #stuff here

class Person:
    #stuff here

class PersonAddressBook:
    client = models.ForeignKey(Client)
    person = models.ForeignKey(Person)
Run Code Online (Sandbox Code Playgroud)

这工作但它将需要更长的时间并使用更多的内存,因为它将加载到我的系统,我想只使用数据库.

clients =[]
adbook = PersonAddressBook.objects.filter(person = person).select_related()
for contact in adbook:
    clients.append(contact.client)
Run Code Online (Sandbox Code Playgroud)

bik*_*der 5

您可以related_name在客户端模型中使用PersonAddressBook:

Client.objects.filter(personaddressbook__person=person)
Run Code Online (Sandbox Code Playgroud)

根据文档应该personaddressbook_set__person但由于某些原因我目前不知道相关名称是以不同的方式生成的.)

我更喜欢明确指定related_name:

class Client(models.Model):
    pass

class Person(models.Model):
    pass

class PersonAddressBook(models.Model):
    client = models.ForeignKey(Client, related_name='addressbooks')
    person = models.ForeignKey(Person, related_name='addressbooks')
Run Code Online (Sandbox Code Playgroud)

现在您可以addressbooks在查询中使用该字段:

Client.objects.filter(addressbooks__person=person)
Run Code Online (Sandbox Code Playgroud)