0ralo
@0ralo
Python backend developer

Почему DRF serializer игнорирует RawQuerySet?

Есть модель
class User(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=256)

Есть сериалайзер
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

И виью
class UserStratsWithNView(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    model = User

    def get_queryset(self, **kwargs):
        pk = self.kwargs.get("pk", None)
        if pk is None:
            return User.objects.raw("SELECT * FROM viewapp_user WHERE username LIKE 'N%%'")
        else:
            query = User.objects.raw("SELECT * FROM viewapp_user WHERE username LIKE 'N%%' and id=%s", [pk])
            print(query) # <RawQuerySet: SELECT * FROM viewapp_user WHERE username LIKE 'N%' and id=9>
            return query

Если выполнить запрос
SELECT * FROM viewapp_user WHERE username LIKE 'N%' and id=9
то бд выдаст результат, однако при запросе на адрес результатов нет
Запрос на /nusers/ выдаёт правильный результат,
Запрос на /nusers/9/ выдаёт не {"detail":"Not found."}, хотя пользователь с таким айди точно есть, и sql генерируется правильный, в чем может быть проблема и как решить?
  • Вопрос задан
  • 29 просмотров
Пригласить эксперта
Ответы на вопрос 1
0ralo
@0ralo Автор вопроса
Python backend developer
Пока нашел костыль как решить. Переписал вьюху так
class UserStratsWithNView(APIView):

    def get(self, request, pk=None):
        if pk is None:
            users = User.objects.raw("SELECT id, username, password FROM viewapp_user WHERE username LIKE 'N%%'")
            serializer = UserSerializer(users, many=True)
            print(dir(serializer))
        else:
            users = User.objects.raw(
                "SELECT id, username, password FROM viewapp_user WHERE username LIKE 'N%%' and id=%s", [pk])
            serializer = UserSerializer(users)
            print(dir(serializer))
        return Response(serializer.data)

Ибо ModelViewSet под капотом сам вызывает методы, которые решают many=

Но при запросе с параметром все равно
ошибка
AttributeError at /va/nusers/9
Got AttributeError when attempting to get a value for field `username` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `RawQuerySet` instance.
Original exception text was: 'RawQuerySet' object has no attribute 'username'.


Если передать сериалайзеру many=True, то ошибки не будет, но тогда в респонсе будут "[]", что немного не в кайф. Тогда изменияем аргумент сериалайзера, так
serializer = UserSerializer(users[0]).
В итоге чудо - работает, непонятно ничего но работает. Сериализация нескольких объектов не вызывает ошибок.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы