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

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

Войти через центр авторизации
Похожие вопросы
Big Smile Coffee Санкт-Петербург
от 150 000 до 200 000 ₽
Сигнатек Новосибирск
До 200 000 ₽
Bell Integrator Екатеринбург
До 150 000 ₽
04 мар. 2024, в 15:37
2000 руб./за проект
04 мар. 2024, в 15:37
850000 руб./за проект
04 мар. 2024, в 15:36
10000 руб./за проект