#django #serialization #django-rest-framework
#джанго #сериализация #django-rest-фреймворк
Вопрос:
У меня есть модель Ingredient
, в которой есть поле ForeignKey. Я использую modelSerializer
для передачи данных. Я передаю recipe_id
URL-адрес вот так recipes/{recipe.id}/ingredients
. Мое текущее решение состоит в том, чтобы изменить request.data
представление, но я уверен, что это правильный способ для такого распространенного случая.
Как лучше всего перейти Recipe
к сериализатору?
models.py
class Ingredient(TimeStamp): name = models.CharField(max_length=50) quantity = models.PositiveSmallIntegerField() recipe = models.ForeignKey( Recipe, on_delete=models.CASCADE, related_name='ingredients', )
serializers.py
class IngredientSerializer(serializers.ModelSerializer): class Meta: model = Ingredient fields = [ 'id', 'name', 'quantity', 'unit', 'recipe' ]
views.py
class IngredientViewSet(viewsets.ModelViewSet): serializer_class = IngredientSerializer def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) request.data['recipe'] = self.kwargs['pk'] serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Ответ №1:
не забудьте передать сериализатор в контекст, который вы можете создать самостоятельно или получить по умолчанию:
context = self.get_serializer_context() serializer = self.get_serializer(data=request.data, context=context)
если вы найдете исходный код для 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 }
он добавляет класс представления и запрос в контекст сериализатора.
в сериализаторе я переопределяю метод create и передаю данные создания, указывающие идентификатор связанного объекта.
class S(ModelSerializer): def create(self, validated_data): validated_data['recipe_id'] = self.kwargs['pk'] return super(S, self).create(validated_data)
и нет необходимости переопределять создание представления