Предоставление данных запроса из представления в сериализатор ModelViewSet Django
Я пытаюсь сделать пользовательскую функцию списка внутри ProductViewSet
, потому что мне нужно загрузить дополнительное поле - самую высокую цену товара в базе данных. Как я могу передать аргумент request
из def list
в сериализатор? То есть сейчас я получаю ошибку 'NoneType' object has no attribute 'user'
в этой строке: if request.user.is_authenticated
.
Итак, как я могу исправить это, чтобы он мог правильно читать self.context.get('request')
?
class ProductViewSet(viewsets.ModelViewSet):
...
def list(self, request):
queryset = Product.objects.all()
serializer = ProductSerializer(queryset, many=True)
return Response(serializer.data)
class ProductSerializer(serializers.ModelSerializer):
...
class Meta:
model = Product
...
def get_is_followed(self, obj):
request = self.context.get('request')
if request.user.is_authenticated:
return Product.objects.filter(id=obj.id, followers=request.user.id).exists()
Вы использовали ModelViewSet, который уже имеет атрибут serializer_class. Вы можете просто указать serializer_class, а о контексте сериализатора позаботится сам DRF. Таким образом, вместо того, чтобы писать serializer = ProductSerializer(queryset, many=True) вы должны написать так:
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = ProductSerializer
queryset = Product.objects.all()
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
Если вас интересует только объект request в качестве контекста для сериализатора, то нет необходимости переопределять метод list в ProductViewSet. По умолчанию сериализатору передаются три контекста (запрос, формат и представление), но если вам нужны дополнительные контексты, вы всегда можете переопределить метод def get_serializer_context(self) в представлении. Это сигнатура по умолчанию метода get_serializer_context:
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}