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

Python 如何计算django联接表中的对象数量?,python,mysql,sql,django,Python,Mysql,Sql,Django,我的问题很简单:我有用户,他们拥有资产或资产,如果您愿意,这些资产属于用户,我无法检索每个用户拥有的资产的数量(计数)。我知道这对你们大多数人来说可能听起来很傻,但我对python/django(来自PHP/MySQL)还不熟悉,我不知道这里的工作原理。我不想使用原始SQL—如果没有其他方法可以工作,这将是我最后的选择 (*)我已从代码中删除所有不相关的RAW 用户 class Users(models.Model): firstname = models.CharField(max_l

我的问题很简单:我有用户,他们拥有资产资产,如果您愿意,这些资产属于用户,我无法检索每个用户拥有的资产的数量(计数)。我知道这对你们大多数人来说可能听起来很傻,但我对python/django(来自PHP/MySQL)还不熟悉,我不知道这里的工作原理。我不想使用原始SQL—如果没有其他方法可以工作,这将是我最后的选择

(*)我已从代码中删除所有不相关的RAW

用户

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()
资产

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()
视图.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 %}
模板

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 %}
{%用于对象列表%中的用户]
{{user.id}
{{user_assets}}
{%endfor%}
我怎样才能得到那个号码?我读过关于聚合、注释和过滤器的文章,但没有真正理解

编辑:

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 %}

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

在您的
用户列表中,使用以下查询集代替使用模型:

from django.db.models import Count

class UserList(ListView):
    queryset = Users.objects.annotate(num_assets=Count('assets'))
然后定义
用户
字段,如下所示:

user = models.ForeignKey('Users', blank=True, null=True, related_name='assets')
@classmethod
def user_assets(cls,user):
    return Assets.objects.select_related('Users').filter(user=user).count()
然后从模板:

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

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

user = models.ForeignKey('Users', blank=True, null=True, related_name='assets')
@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) 
这应该很好用,你可以在贝壳里试试

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

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(),还添加了适合您特定用例的示例。

您正在做一些奇怪的事情。使用django提供给您的相关管理器。我将以基于函数的视图的形式编写视图:

视图.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 %}
{%用于对象列表%中的用户]
{{user.id}
{{user.assets\u set.count}}
{%endfor%}
您还可以使用计数进行注释。但在游泳之前要学会漂浮:)


顺便说一句,你应该称你的模型为“用户”和“资产”,而不是“用户”和“资产”。

你需要使用sql连接,如果你不想弄乱原始sql,你可以试试django的,然后,但是你需要外键来工作。我有一个从资产到用户的外键。许多资产属于一个用户,但两个用户不能拥有相同的资产。a是的,你是对的,没有注意到这一点,请尝试选择相关资产,也许可以。它没有。我尝试了“return cls.objects.select_related(None).count()”和“return cls.objects.select_related('assets').count()”,我总是得到全部资产。开始时的cls是什么?您需要类似这样的内容:
Assets.objects.prefetch_related('Users').filter(user=user).count()
我得到的是“'ForeignRelatedObjectsDescriptor'对象没有属性'count'”'ForeignRelatedObjectsDescriptor'对象没有属性'all',我觉得我必须导入一些lib@RobDel哦,我觉得问题是,您访问的是类而不是视图中的对象(
self.model
)。@RobDel好的,我制作了最终版本,请试用,在这种情况下您不需要自定义方法。我应该将代码的第二段放在哪里?在views.py中?第一部分还提供了一个错误“user_assets()缺少1个必需的位置参数:'user'”是的,在视图中,您确定要将用户对象传递给资产吗?此pk=1只是一个示例,您可能没有id为1的用户,关键是要将用户实例作为参数传递给筛选器,以便django将选择范围缩小到用户的一个实例。类型对象“Users”没有属性“all”。有什么想法吗?