如何计算django连接表中的对象数量?

时间:2014-02-02 15:56:26

标签: python mysql sql django

我的问题很简单:我拥有属于用户的资产资产用户如果您愿意,我无法做到检索每个用户所拥有的资产的数量(计数)。我知道这对你们大多数人来说可能是愚蠢的,但我是python / django(来自PHP / MySQL)的新手,我不知道这里的工作原理。我不想参与原始SQL - 这将是我的最后选择如果没有其他工作。

(*)我已从代码

中删除了所有不相关的原始数据

用户

class Users(models.Model):
    firstname = models.CharField(max_length=100)
    lastname = models.CharField(max_length=100)

资产

class Assets(models.Model):
    serial = models.CharField(unique=True, max_length=100)
    user = models.ForeignKey('Users', blank=True, null=True)

    # this is what I am playing with to retrieve the number of assets each user owns
    @classmethod
        def user_assets(self):
            return Assets.objects.filter(user=user).count()

views.py

class UserList(ListView):
    model = Users
    def get_context_data(self, **kwargs):
        context = super(UserList, self).get_context_data(**kwargs)
        context['user_assets'] = self.model.user_assets()
        return context

模板

{% for user in object_list %}
     <tr>
         <td>{{ user.id }}</td>
         <td>
             {{ user_assets }}
         </td>
     </tr>
{% endfor %}

我怎样才能得到这个号码?我已阅读有关聚合,注释和过滤器的信息,但无法真正理解它。

编辑:

我正在寻找一个简单的解决方案,使用基于类的视图并且可以轻松扩展(我可能希望稍后添加其他模型)

3 个答案:

答案 0 :(得分:2)

UserList而不是使用模型中,请使用此查询集:

from django.db.models import Count

class UserList(ListView):
    queryset = Users.objects.annotate(num_assets=Count('assets'))

并定义您的user字段,如下所示:

user = models.ForeignKey('Users', blank=True, null=True, related_name='assets')

然后从模板:

{{ user.num_assets }}

另外请记住,使用单数模型名称是一种很好的做法,以避免与反向关系名称混淆。

答案 1 :(得分:2)

你做的很奇怪。使用django给你的相关经理。我将视图写为基于函数的视图:

<强> views.py

def users_list(request):
    object_list = Users.objects.all()
    render(request, 'mytemplate.html', { 'object_list': object_list })

您可以通过RelatedManager直接在模板中获取计数:

<强> mytemplate.html

{% for user in object_list %}
 <tr>
     <td>{{ user.id }}</td>
     <td>
         {{ user.assets_set.count }}
     </td>
 </tr>
{% endfor %}

您还可以使用计数进行注释。但是在你游泳之前学会漂浮:)

顺便说一句,你应该打电话给你的模特&#34;用户&#34;和&#34;资产&#34;,而不是用户和资产。

答案 2 :(得分:1)

您需要使用select_related()count()并将用户实例作为参数传递给类方法,如下所示:

@classmethod
def user_assets(cls,user):
    return Assets.objects.select_related('Users').filter(user=user).count()

然后像这样使用它:

user = Users.objects.all()[0] # some user object (this assumes you have at least one user)
Assets.user_assets(user) 

这应该可以正常工作,你可以在shell中试试。

在您的上下文中,这将使用如下:

user = self.model.all()[0] # or get or filter just get some particular user
context['user_assets'] = Assets.user_assets(user)

编辑:添加链接,以及Users.object.all()而不是Users.object.get(),还添加了适合您特定用例的示例。