Django вложенные объекты, разные сериализаторы GET и POST - PullRequest
1 голос
/ 09 марта 2020

это продолжение этого вопроса, которое у меня было здесь .

Теперь я могу POST новый объект AP, используя первичный ключ пользователя и после комментирования этой строки в сериализаторе AP user = UserIndexSerializer():

Запрос почтальона:

{
    "user":1,
    "name":"Max AP 05"
}

Однако у меня сейчас проблема в том, что первоначальный UserIdexSerializer становится бесполезным.

Этот сериализатор определяет поля для отображения в запросе GET, но в результате накладывает поля, необходимые в запросе POST. Я пытаюсь сделать следующее:

  • POST новый объект AP только с использованием идентификатора пользователя
  • Показать поля UserIndexSerializer во время запроса GET (first_name, last_name, но не ID)

Как я могу сделать эту работу?

Я нашел и прочитал эту запись .

Я пытался использовать разные виды, один для перечисления моих моделей и один для создания новой:

from rest_framework import serializers
from ..models.model_art_piece import AP
from .serializers_user import *


class APIndexSerializer(serializers.ModelSerializer):
    user = UserIndexSerializer()

    class Meta:
        model = AP
        fields = [
            'id',
            'user',
            'name'
        ]

class APCreateSerializer(serializers.ModelSerializer):
    user = UserIDSerializer()

    class Meta:
        model = AP
        fields = [
            'id',
            'user',
            'name'
        ]

    def create(self, validated_data):
        ap = AP.objects.create(**validated_data)
        return ap

class APDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = AP
        fields = '__all__'

И я также попытался создать различные сериализаторы:

from rest_framework import serializers
from ..models.model_user import User


class UserIndexSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'first_name',
            'last_name'
        ]

class UserIDSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id'
        ]

class UserDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

Это не работает вообще, кто-нибудь может мне помочь с этим?

Ответы [ 2 ]

2 голосов
/ 09 марта 2020

Если я правильно понял, вы хотите получить вложенный объект во время get. У меня была та же проблема, которую я решил с этим в моем сериализаторе.

class APIndexSerializer(serializers.ModelSerializer):
    class Meta:
        model = AP
        fields = ['id','user','name']

    def to_representation(self, obj):
        self.fields['user'] = UserIndexSerializer()
        return super(APIndexSerializer, self).to_representation(obj)

Вы можете с этим создать с идентификатором и получить с вложенной информацией пользователя.

1 голос
/ 09 марта 2020

Я приведу пример, объясняющий, как использовать разные сериализаторы в GET / POST для реляционных полей.

Существует модель Ticket, и ее внешний ключ относится к модели пользователя. В вашем POST для создания заявки вы хотите, чтобы идентификатор пользователя создавал объект. В вашем GET, чтобы получить детали билета, вы хотите показать данные пользователя, а не идентификаторы.

Ticket(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)

В вашем файле сериализатора у вас есть

class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('first_name', 'last_name')


class TicketPostSerializer(serializer.ModelSerializer):
    class Meta:
        model = Ticket
        fields = '__all__'


class TicketDetailSerializer(serializer.ModelSerializer):
    user = UserDetailSerializer(read_only=True)
    class Meta:
        model = Ticket
        fields = '__all__'

Затем, в функции просмотра билета , тогда у вас есть:

class TicketViewSet(viewsets.ModelViewSet):
    serializer_class = TicketPostSerializer
    def get_serializer_class(self):
        if self.action in ['list', 'retrieve']:
            return TicketDetailSerializer

Все готово, вы можете go.

...