Django Rest Framework RetreiveAPIView get () вернул 2 результатов - PullRequest
0 голосов
/ 14 января 2019

У меня есть проект django с фреймворком django rest. Я пытаюсь использовать Retreive API View для возврата сведений об участниках. Я хочу получить все записи о членах на основе параметра, который передается в URL с именем группы. Я пытался использовать .get() и .filter(). .get() вернул error of returning more than 2 items. .filter() не является частью диктата.

Я пытался .list и .retrieve

Как я могу получить объекты данных, основанные на более чем 1 элементе. Вот мой взгляд, которому я призываю.

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

1018 * URLs *

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

_________________________________________-

UPDATE:

, поэтому я получаю сообщение об ошибке при переопределении списка:

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

URLs:

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

Ответы [ 3 ]

0 голосов
/ 14 января 2019

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. Так что не делайте .filter() на self.kwargs.

0 голосов
/ 14 января 2019

В дополнение к ответу @ Alex вам необходимо реализовать метод фильтра или обычно добавить бэкэнд фильтра, чтобы иметь возможность фильтровать наборы запросов на основе параметров фильтра 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-фильтра для более подробной информации о том, как его использовать.

0 голосов
/ 14 января 2019

RetrieveAPIView предназначен для получения одного экземпляра. Вы должны использовать ListAPIView . И используйте get_queryset метод вместо get_object

ListAPIView вызывает сериализатор с параметром many=True, который возвращает список объектов вместо одного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...