问题描述
我正在遵循Django REST框架的课程,但是在尝试将 ordering 配置从 django_filters 设置为 ViewSet 时遇到了麻烦。
ordering = ('-members__count')
在课程的原始代码中,-members__count
用作查询以返回成员总数,但是当我尝试使用相同的语法时,出现此错误:
错误:
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
也许我误会了这个错误,但是所有这些建议的选项都对应于我模型中的Fields。另外,在“课程”中,它表示这是一种查询表示形式,用于获取该字段的总数,因此我对此感到有些困惑。
无论如何,这是我的代码的简历,但是如果需要,您也可以在此存储库中查看我的完整详细代码: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
模型的属性。在count
模型上找不到User
。
我了解您要执行的操作是按照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