Django queryset附加或注释相关的对象字段

sta*_*alk 11 django django-models django-queryset

需要附加到queryset结果相关的对象字段.

楷模:

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")
Run Code Online (Sandbox Code Playgroud)

我可以做这个:

>>> User.objects.all().values('name', 'member_from__status')
[{'member_from__status': u'accepted', 'name': 'Ann'}, {'member_from__status': u'thinking', 'name': 'John'}]
Run Code Online (Sandbox Code Playgroud)

'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
Run Code Online (Sandbox Code Playgroud)

queryset中的每个实例都有一个'member_from__status'字段,其中包含相应的值:

>>> users_with_status[0].member_from__status
u'accepted'
Run Code Online (Sandbox Code Playgroud)

如何实现这一目标?

gog*_*gaz 12

你可以使用annotateF

>>> from django.db.models import F
>>> u = User.objects.all().annotate(member_from__status=F('member_from__status'))
>>> u[0].member_from__status
'accepted'
Run Code Online (Sandbox Code Playgroud)

用Django 1.11测试