【问题标题】:how to use a queryset expression in a then clause in conditional annotation in Django如何在Django条件注释的then子句中使用查询集表达式
【发布时间】:2019-01-18 01:50:15
【问题描述】:

我有两种模型,一种是组织,另一种是组织中用户的成员和角色

class Organization(models.Model):
    name = models.CharField(blank=False,null=False,max_length=100, unique=True)

class Member(models.Model):
    user_request = models.ForeignKey('accounts.User',on_delete=models.CASCADE,related_name="member_user_request")
    user_second = models.ForeignKey('accounts.User',on_delete=models.CASCADE,blank=True,null=True, related_name="member_user_second")
    role = models.ForeignKey(RoleOrganization,on_delete=models.CASCADE, verbose_name=_('Rol'))
    status = models.ForeignKey(Status,on_delete=models.CASCADE, verbose_name=_('Status'))
    organization = models.ForeignKey(Organization,on_delete=models.CASCADE, verbose_name=_('Organization'))

我正在尝试使用带有 case 子句的注释,我想通过此表达式获取组织中用户的角色:

my_organizations = Member.objects.filter(
        Q(user_request_id=self.request.user.id, status__name="accepted", type_request__name="request") |
        Q(user_second_id=self.request.user.id, status__name="accepted", type_request__name="invitation")
    )

Organization.objects.annotate(
        rol=Case(
            When(id__in=list(my_organizations.values_list('organization_id', flat=True)),
                 then=Value(my_organizations.get(organization_id=F('id')).role.name)),
            default=None, output_field=CharField()
        )
    )

这里的问题是 then 表达式没有获取主查询集中对象的 id,如果我返回然后只是 F('id') 表达式获取主查询集中 id 的值查询集,但我可以使用过滤器或任何查询集表达式与主对象的某些值。

它有办法做到这一点。 PS:我只是将部分代码放在这里,但如果您需要了解更多信息,请告诉我

【问题讨论】:

  • 你能重新解释一下你想要完成什么吗?我感觉你从错误的方向接近这个,但我不确定你想提取什么数据。

标签: python django django-models django-queryset


【解决方案1】:

我认为你可以使用Subquery 来做到这一点:

from django.db.models import OuterRef, Subquery

members = Member.objects.filter(
           Q(user_request_id=self.request.user.id, status__name="accepted", type_request__name="request") |
           Q(user_second_id=self.request.user.id, status__name="accepted", type_request__name="invitation")
        )

member_subquery = members.filter(organization=OuterRef('pk'))

organizations = Organization.objects.annotate(member_role=Subquery(member_subquery.values('role')[:1]))

print(organizations.values('member_role'))

【讨论】:

  • 非常感谢您的回答,它工作得很好,但是,您能解释一下这如何满足我的需求吗?再次感谢
  • 好吧,在member_subquery 中,当我使用Subquery 时,我使用OuterRef 来匹配外部Organization 查询。这里我只能从子查询中注释一个值,所以我使用[:1] 来获取Member 查询集值的第一个元素。我希望这些信息会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多