Django Rest Framework RetreiveAPIView get()返回2个结果

时间:2019-01-14 02:07:32

标签: python django django-rest-framework

我有一个带有django rest框架的django项目。我正在尝试使用Retreive API视图返回成员详细信息。我想根据使用组名称在url中传递的参数来获取所有成员记录。我尝试使用.get().filter().get()返回了error of returning more than 2 items.filter()不是字典的一部分。

我尝试了.list.retrieve

如何检索包含多个项目的数据对象。这是我正在致电的视图。

class MemberDetailView(RetrieveAPIView):
    queryset = Member.objects.all()
    serializer_class = MemberSerializer

    def get_object(self):
        return self.queryset.filter(group__name=self.kwargs.filter('name'))

模型

class Member(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    host = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.group.name + ' - ' + self.user.username

网址

path('members/', MemberListView.as_view()),
path('members/<name>', MemberDetailView.as_view()),

_________________________________________-

更新:

所以当我覆盖列表时出现错误:

TypeError at /api/groups/members/homiez list() got an unexpected keyword argument 'name'

当我不覆盖列表时,我得到一个空的结果对象。

这是我现在拥有的代码...

class MemberGroupListView(ListAPIView):
    serializer_class = MemberSerializer

    def get_queryset(self):
        return Member.objects.filter(group__name=self.request.query_params.get('name'))

    def list(self, request):
        # Note the use of `get_queryset()` instead of `self.queryset`
        queryset = self.get_queryset()
        serializer = MemberSerializer(queryset, many=True)
        return Response(serializer)

模型

class Group(models.Model):
    name = models.CharField(max_length=42)
    description = models.CharField(max_length=220)
    user_count = models.IntegerField()
    status = models.CharField(max_length=12)
    image = models.ImageField(upload_to='group_images/')
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name + ' - ' + self.created_by.username

class Member(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    host = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.group.name + ' - ' + self.user.username

网址:

path('members/<name>', MemberGroupListView.as_view()),

3 个答案:

答案 0 :(得分:3)

RetrieveAPIView设计用于检索单个实例。您应该改用ListAPIView。并使用get_queryset方法代替get_object

ListAPIView使用many=True参数调用序列化程序,该参数返回一个对象列表,而不是一个对象列表。

答案 1 :(得分:2)

Django ORM get仅用于检索一个对象。 filter可用于查询查询集中的多个对象。因此,要检索多个内容,您必须使用过滤器。

在您的View中,我认为您需要覆盖list方法。

class MemberDetailView(RetrieveAPIView):
    serializer_class = MemberSerializer

    def get_queryset(self):
        """
        This view should return a list of all the purchases for
        the user as determined by the username portion of the URL.
        """
        username = self.kwargs['username']
        return Purchase.objects.filter(group__name=self.request.query_params.get('name'))

    def list(self, request):
        # Note the use of `get_queryset()` instead of `self.queryset`
        queryset = self.get_queryset()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

注意:self.request.query_params.get()是从request对象检索数据的方式。它是关于字典操作而不是ORM操作的。因此,请勿在{{1​​}}上进行.filter()

答案 2 :(得分:1)

除了@Alex的答案外,您还需要实现filter方法或典型地添加filter后端,以便能够基于url过滤器参数来过滤查询集。 我会使用django-filter作为过滤器后端,因为它非常有效,灵活,并且已经成为Django应用程序的相当标准。

您需要这样的东西:

from django_filters import rest_framework as filters

class MemberDetailView(RetrieveAPIView):
    queryset = Member.objects.all()
    serializer_class = MemberSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = ('user', 'host', 'group')

您可以阅读Django过滤器文档,以获取有关如何使用它的更多详细信息。