我目前正在使用django 1.8,我想创建一种更智能的方式来显示有关用户的信息。说我有这样的事情:
class User(models.Model):
name = models.CharField()
class Invitation(models.Model):
inviter = models.ForeignKey(User)
invitee = models.ForeignKey(User)
我想创建一个字段,该字段是邀请者邀请的用户的唯一编号。我可以看到如何通过set("SELECT invitee FROM INVITATIONS WHERE inviter = 'my-user';")
之类的方式完成此操作,但是如果我希望在管理面板中显示它,是否有一种简单的方式来呈现它?
另外,我希望每个用户都能这样做,所以感觉有一种简单的方法可以为表中的每个用户生成一个字段。
答案 0 :(得分:1)
首先,让我们正确设置related_name
- 这有助于减少代码中的大量混淆。
class Invitation(models.Model):
inviter = models.ForeignKey(User, related_name="invitation_sent")
invitee = models.ForeignKey(User, related_name="invitation_recv")
使用related_name
设置,我们可以执行查询,例如
user = User.objects.get(pk=1)
# retrieve all invitation objects sent by this user
user.invitation_sent.all()
# retrieve all invitation objects received by this user
user.invitation_recv.all()
现在我们可以非常轻松地计算用户发送的独特邀请的数量:
# count number of distinct invitee for user
user.invitation_sent.all().values('invitee').distinct().count()
接下来,我们实际上可以计算用户在所有用户的单个数据库查询中邀请的唯一身份用户数:
user_list = User.objects.all().annotate(
uniq_inv=Count('invitation_sent__invitee', distinct=True)
)
返回的每个用户对象都有一个名为uniq_inv
的附加属性,其中包含用户邀请的唯一用户数
for user in user_list:
print(user.name + ' invited ' + user.uniq_inv + ' unique users')
要将此应用于管理界面,您需要覆盖get_queryset
方法:
class MyAdmin(admin.ModelAdmin):
...
list_display = [..., 'uniq_inv']
def uniq_inv(self, obj):
return obj.uniq_inv
uniq_inv.short_description = 'Unique Invitees'
def get_queryset(self, request):
qs = super(MyAdmin, self).get_queryset(request)
qs = qs.annotate(uniq_inv=Count('invitation_sent__invitee', distinct=True))
return qs
答案 1 :(得分:0)
您可以使用注释,它允许将计算字段添加到查询集。
模特:
class User(models.Model):
name = models.CharField()
class Invitation(models.Model):
inviter = models.ForeignKey(User,related_name="inviter_user")
invitee = models.ForeignKey(User,related_name="invited_user")
查询集:
from django.db.models import Count
q = Invitation.objects.annotate(count_invitee=Count('invitee')).all()
现在" count_invitee" field包含每个邀请对象的编号。
如果您想从用户端过滤被邀请者。 对于单个用户:
User.objects.get(pk=1).invited_user.all.count()
对于所有用户queryset:
User.objects.annotate((count_invitee=Count('invited_user')).all()