gpt4 book ai didi

Django 查询集附加或注释相关对象字段

转载 作者:行者123 更新时间:2023-12-04 00:50:20 25 4
gpt4 key购买 nike

需要附加到查询集结果相关的对象字段。

楷模:

class User(models.Model):
name = models.CharField(max_length=50)
friends = models.ManyToManyField('self', through='Membership',
blank=True, null=True, symmetrical=False)


class Membership(models.Model):
status = models.CharField(choices=SOME_CHOICES, max_length=50)
from_user = models.ForeignKey(User, related_name="member_from")
to_user = models.ForeignKey(User, related_name="member_to")

我可以做这个:
>>> User.objects.all().values('name', 'member_from__status')
[{'member_from__status': u'accepted', 'name': 'Ann'}, {'member_from__status': u'thinking', 'name': 'John'}]
'member_from__status'包含我需要的信息。但与它一起,我还需要一个模型实例。

我想要的是:
>>> users_with_status = User.objects.all().do_something('member_from__status')
>>> users_with_status
[<User 1>, <User 2>]

>>> users_with_status[0] # <-- this is an object, so i can access to all its methods

查询集中的每个实例都有一个具有相应值的“member_from__status”字段:
>>> users_with_status[0].member_from__status
u'accepted'

这怎么可能实现?

最佳答案

您可以使用 annotate F

>>> from django.db.models import F
>>> users = User.objects.all().annotate(member_from__status=F('member_from__status'))
>>> users[0].member_from__status
'accepted'
使用 Django 版本 1.11 和 2.2 测试

回应评论
在这里,我想我们对 member_to__status 很感兴趣比 member_from__status (我们希望用户被要求接受友谊,而不是相反)
这是我的 membership的内容 table :
status   |  from|   to
---------+------+-----
accepted | 1| 2
accepted | 2| 3
refused | 3| 1
由于“ it's not possible to have a symmetrical, recursive ManyToManyField ”(例如,用户 1 接受了用户 2,因此用户 1 现在在用户 2 的 friend 列表中,但用户 2 也在用户 1 的 friend 中),这就是我检索所有实际 friend 的方式:
>>> for user in User.objects.all():
... friends = user.friends.filter(member_to__status='accepted')
... print(str(user.id) + ': ' + ','.join([str(friend.id) for friend in friends]))
1: 2
2: 3
3:
如果你想拥有 <User 1><User 2>的 friend ,建议再加一个 Membership当 1 到 2 的友谊被接受时。
这里我们假设 Membership只能接受一次,因此最好添加 unique-together选项。尽管如此,如果我们有几个 Membershipfrom_user ,这就是发生的事情:
>>> # <Insert several Membership from one to another User>
>>> Membership.objects.filter(from_user__id=1, to_user__id=2).count()
3
>>> users = User.objects.annotate(member_from__id=F('member_from__id'))
>>> print('User Membership')
... for user in users:
... print("%4d %10d" % (user.id, user.member_from__id))
User Membership
1 1
2 2
1 3 # User 1 again
1 4 # User 1 again
3 None

关于Django 查询集附加或注释相关对象字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20139372/

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