我希望获得一个查询集及其组成员资格,以避免昂贵的额外数据库命中,并使模板中的内容管理变得更加容易。
最初我尝试预取用户所属的组:
def get_queryset(self):
User.objects.filter(is_active=True).prefetch_related('groups')
但是,这使得很难根据组显示和隐藏模板中的内容:
{{ user.groups.all }}
给出
<QuerySet [<Group: Managers>]>
然后我认为注释可能会更好is_manager
和is_head
,例如:
from django.db.models import BooleanField, Case, Value, When
def get_queryset(self):
'''Return both active and inactive users for managers
Annotate with is_manager = True/False
'''
query = When(groups__name__in=[MANAGER_GROUP_NAME, ], then=Value(1))
return self.model.objects.all().annotate(
is_manager=Case(
query,
default=Value(0),
output_field=BooleanField()
)
)
哪个工作正常,但给了我一个错误:
Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'my_site.auth_group.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
但是在模板中很容易使用:
{% if user.is_manager %} Manager {% else %} Normal user {% endif %}
有更简单的方法吗?
修改
最终查询:
self.model.objects.prefetch_related('groups').all().annotate(
is_manager=Case(
When(
groups__id__exact=1, then=True
), default=False, output_field=BooleanField()
)
).values("pk", "id", "email", "is_manager")
答案 0 :(得分:1)
您的方法很好的尝试。
首先,如果可能,请考虑使用组ID而不是组名来标识managers
。将显着提高查询性能和拼写相关的错误。
以下是我尝试过并为我工作的快速代码段。 (关于postgres)。
User.objects.prefetch_related("groups").annotate(
is_super=Case(
When(
groups__id__in=[1, 2,3 ], then=1
), default=0, output_field=IntegerField()
)
).order_by("id").values_list("id", "username", "is_super")