Django REST 框架 |从 ManyToMany 字段按计数排序

Django REST Framework | Ordering by Count from a ManyToMany Field

我正在学习 Django REST Framework 的课程,但我在尝试从 django_filters[=38= 设置 ordering 配置时遇到了困难] 变成 ViewSet.

ordering = ('-members__count')

在课程的原始代码中,-members__count 被用作 return 成员总数的查询,但是当我尝试使用相同的语法时,我得到了这个错误:

错误:

Cannot resolve keyword 'count' into field. Choices are: auth_token, circle, created, date_joined, email, first_name, groups, id, invitation, invited_by, is_active, is_client, is_staff, is_superuser, is_verified, issued_by, last_login, last_name, logentry, membership, modified, password, phone_number, profile, user_permissions, username

也许我误解了这个错误,但所有这些建议的选项都对应于我模型中的字段。此外,在课程中它指出这是一种查询表示格式,用于获取该字段的总数,所以我对此有点困惑。

无论如何,这是我的代码的简历,但您也可以在此 repo 中查看我的完整详细代码以备不时之需:https://github.com/cadasmeq/comparte_ride/tree/master/cride/circles.

查看:

# Filters
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

class CircleViewSet(mixins.CreateModelMixin,
                    mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.ListModelMixin,
                    viewsets.GenericViewSet):
    """Circle view set."""

    serializer_class = CircleModelSerializer
    lookup_field = 'slug_name'

    # Filters
    filter_backends = (SearchFilter, OrderingFilter, DjangoFilterBackend)
    search_fields = ('slug_name', 'name')
    ordering_fields = ('rides_offered', 'rides_taken', 'name', 'created', 'member_limit')
    ordering = ('-members__count', '-rides_offered', '-rides_taken')
    filter_fields = ('verified', 'is_limited')

型号:

class Circle(CRideModel):
"""Circle model.

A circle is a private group where rides are offered and taken
by its members. To join a circle a user must receive an unique
invitation code from an existing circle member.
"""

members = models.ManyToManyField(
    "users.User",
    through='circles.Membership',
    through_fields=('circle', 'user')
)

先谢谢你们了,我对生疏的英语感到抱歉哈哈

您出现此错误是因为您正在尝试访问 User 模型的 属性。它在 User 模型上找不到 count。 据我了解,您要做的是按 ManyToManyField members.

上每个圈子的成员数量排序

为此我会使用 annotate,将 members__count 重命名为 members_count 并执行类似(未测试)的操作:

from django.db.models import Count

class CircleViewSet(mixins.CreateModelMixin,
                    mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.ListModelMixin,
                    viewsets.GenericViewSet):
    """Circle view set."""

    serializer_class = CircleModelSerializer
    lookup_field = 'slug_name'

    # Filters
    filter_backends = (SearchFilter, OrderingFilter, DjangoFilterBackend)
    search_fields = ('slug_name', 'name')
    ordering_fields = ('rides_offered', 'rides_taken', 'name', 'created', 'member_limit')
    ordering = ('-members_count', '-rides_offered', '-rides_taken')
    filter_fields = ('verified', 'is_limited')

    def get_queryset(self):
        """Restrict list to public-only."""
        queryset = Circle.objects.annotate(members_count=Count('members')).all()
        if self.action == 'list':
            return queryset.filter(is_public=True)
        return queryset