Задать вопрос
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 генерируется правильный, в чем может быть проблема и как решить?
  • Вопрос задан
  • 52 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 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]).
В итоге чудо - работает, непонятно ничего но работает. Сериализация нескольких объектов не вызывает ошибок.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы
Wanted. Москва
от 60 000 до 120 000 ₽
Wanted. Санкт-Петербург
До 200 000 ₽