创建Django表,显示有关用户的信息

创建Django表,显示有关用户的信息,django,Django,我目前正在使用django 1.8,我想创建一种更智能的方式来显示用户信息。假设我有这样的东西: class User(models.Model): name = models.CharField() class Invitation(models.Model): inviter = models.ForeignKey(User) invitee = models.ForeignKey(User) 我想创建一个字段,它是邀请者邀请的用户的唯一编号。我可以看到如何使用s

我目前正在使用django 1.8,我想创建一种更智能的方式来显示用户信息。假设我有这样的东西:

class User(models.Model):
    name = models.CharField()

class Invitation(models.Model):
    inviter = models.ForeignKey(User)
    invitee = models.ForeignKey(User)
我想创建一个字段,它是邀请者邀请的用户的唯一编号。我可以看到如何使用
set(“从邀请中选择被邀请者,其中邀请者='my user';”)
之类的东西来实现这一点,但是如果我想在管理面板中显示这一点,是否有一种简单的方法来表示这一点


另外,我希望对每个用户都这样做,因此感觉有一种简单的方法可以为表中的每个用户生成字段。

您可以使用annotate,它允许将计算字段添加到queryset

型号:

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”字段中有每个邀请对象的编号

如果要从用户端筛选被邀请者。 对于单个用户:

User.objects.get(pk=1).invited_user.all.count()
对于所有用户查询集:

User.objects.annotate((count_invitee=Count('invited_user')).all()

首先,让我们设置适当的
相关名称
——这将有助于减少代码中的大量混乱

class Invitation(models.Model):

    inviter = models.ForeignKey(User, related_name="invitation_sent")
    invitee = models.ForeignKey(User, related_name="invitation_recv")
使用
related\u 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()
接下来,我们可以实际计算一个用户在单个数据库查询中邀请的所有用户的唯一用户数:

返回的每个用户对象将有一个名为
uniq\u inv
的附加属性,该属性包含用户邀请的唯一用户的计数

for user in user_list:
    print(user.name + ' invited ' + user.uniq_inv + ' unique users')
要将此应用于管理界面,您需要覆盖
get\u 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

我指的是用户邀请的用户数量。因此,它将是所有被邀请者的集合,其中用户是被邀请者。它将每次运行这个吗?我觉得随着数据库的增长,这可能会在计算上变得非常昂贵。这个答案是错误的-注释将返回用户收到的邀请数量,而不是用户的唯一被邀请者数量。即使注释被切换到count
inviter\u user
(Rob正在寻找),它仍然不会计算被邀请的唯一用户的数量。
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