Django Rest Framework ViewSets возвращает выбранные записи, а не все записи в виде списка - PullRequest
0 голосов
/ 28 января 2019

У меня есть приложение django.У меня есть одна часть моего приложения, которая не работает, как я ожидал.На данный момент я использую наборы представлений django.То, что я хочу, это два в основном иметь два разных представления списка в одном наборе.1, которая возвращает все учетные записи в наборе учетных записей, и другое представление списка, которое возвращает все учетные записи, связанные с пользователем, на основе внешней клавиши пользователя в модели учетных записей.

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

class AccountViewSet(viewsets.ModelViewSet):
    serializer_class = AccountSerializer
    queryset = Account.objects.all()
    lookup_field = 'user__username'

    def list(self, request):
        queryset = Account.objects.all()
        serializer_class = AccountSerializer

        def get_object(self):
            return self.queryset.get(user__username=self.kwargs.get('username'))

** ОБНОВЛЕНИЕ **

class AccountViewSet(viewsets.ModelViewSet):
    queryset = Account.objects.all();
    serializer_class = AccountSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = ('user', 'name', '_class')
    lookup_field = 'user__username'

    # def get_queryset(self):
    #     return self.queryset.filter(user__username=self.kwargs.get('username'))

работает, когда с одним пользователем связана одна учетная запись.не работает с более чем 2 учетными записями с ошибкой:

MultipleObjectsReturned at /api/users/accounts/omarjandali/
get() returned more than one Account -- it returned 2!

другие попытки не возвращают учетные записи с определенным пользователем или без пользователя в конечной точке.

Самая большая проблема заключается в том, что она возвращаетидентификатор пользователя, а не имя пользователя.

enter image description here

текущий код:

serializers.py:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'is_staff')

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ('user', 'gender', 'phone', 'ip_address', 'dob_month', 'dob_day',
                  'dob_year', 'address_street', 'address_city', 'address_state',
                  'address_postal', 'address_country', 'profile_pic', 'role')

class FriendSerializer(serializers.ModelSerializer):
    class Meta:
        model = Friend
        fields = ('requested', 'friended', 'status', 'blocked')

class AccountSerializer(serializers.ModelSerializer):
    user = UserSerializer(
        read_only = True,
    )

    class Meta:
        model = Account
        fields = ('user', '_id', 'name', 'balance', 'currency', 'bank_name',
                  'routing', '_class', 'type', 'active', 'main', 'synapse')

Views.py:

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    lookup_field = 'username'

class ProfileViewSet(viewsets.ModelViewSet):
    serializer_class = ProfileSerializer
    queryset = Profile.objects.all()
    lookup_field = 'user__username'

class FriendViewSet(viewsets.ModelViewSet):
    serializer_class = FriendSerializer
    querset = Friend.objects.all()
    lookup_field = 'user__username'

class AccountViewSet(viewsets.ModelViewSet):
    queryset = Account.objects.all();
    serializer_class = AccountSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('user',)

URL:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'profiles', ProfileViewSet, basename='profile')
router.register(r'friends', FriendViewSet, basename='friend')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = router.urls

1 Ответ

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

Во-первых, у вас много проблем с вашим кодом.Если вам нужно вернуть список, вам следует отфильтровать метод get_object.он предназначен для возврата только одного экземпляра, так что в методе get_queryset.Во-вторых, у вас есть get_object() внутри вашего метода списка, что неправильно.В-третьих, назначение класса сериализатора в методе list не имеет смысла.Он назначается до того, как этот метод даже вызывается.

Теперь вернемся к вашему вопросу: «список» - это действие набора данных, и вы не можете реализовать его дважды.Вместо этого вы можете добавить дополнительное действие в конечную точку списка.Для этого просто добавьте метод в метод действия в наборе.

В вашем конкретном случае я бы сделал следующее: я введу переменную экземпляра qs_type, которая используется для управления типом результата, возвращаемого методом get_queryset().

Примерно так:

def __init__(self, *args, **kwargs):
    self.qs_type = 'user_only'
    super().__init__(*args, **kwargs)

def get_queryset(self):
    if self.qs_type == 'user_only':
        qs = Account.objects.filter(username=self.kwargs.get('username'))
    else:
        qs = Account.objects.all()
    return qs)


@action(detail=False, methods=['get'])
def all(self, request, *args, **kwargs):
    self.qs_type = 'all'
    return self.list(request, *args, **kwargs)

Предполагается, что по умолчанию возвращается фильтрованная по имени пользователя версия, а все учетные записи будут возвращены в новом действии.Вы можете сделать qs_type логическим значением, если вы уверены, что вам не нужно больше подобных действий, но я сделал это на всякий случай.Я не знаю, как настроен ваш URL-адрес, поэтому я не знаю, как имя пользователя извлекается из URL-адреса kwargs, но этот код должен помочь вам решить вашу проблему

...