Переопределить django сериализатор или метод создания моделей - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь добавить данные в свою базу данных. С этой целью у меня есть функция vue:

@api_view(['POST'])
  def update_add_bges(request):
    serializer = BGESSerializer(data=request.data)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

, которая вызывает сериализатор для добавления новых данных в базу данных:

class BGESSerializer(serializers.ModelSerializer):    
  laboratoire = LaboratoiresSerializer()

  class Meta:
    model = BGES
    fields = '__all__'

  def create(self, validated_data):
    laboratoire_data = validated_data.pop('laboratoire')
    laboratoire_oj = Laboratoire.objects.create(**laboratoire_data)
    validated_data["laboratoire"] = laboratoire_obj["pk"]
    bges = BGES.objects.create(**validated_data)
    return bges

Проблема заключается в том, что мой Laboratoire classe также является вложенным и должен добавлять экземпляры из другого класса:

class LaboratoiresSerializer(serializers.ModelSerializer):

  tutelles = TutellesSerializer(many=True)

  class Meta:
    model = Laboratoire
    fields = '__all__'

  def create(self, validated_data):
    tutelles_data = validated_data.pop('tutelles')
    laboratoire = Laboratoire.objects.create(**validated_data)
    for tutelle_data in tutelles_data:
      t = Tutelle.objects.get(nom=tutelle_data["nom"])
      laboratoire.tutelles.add(t)
    return laboratoire

Это не работает, потому что не вызывается, так как это создание сериализатора, а не создание моделей. Как я должен сделать? Когда я добавляю Laboratoire, у меня есть Tutelle для создания ... Должен ли я реализовать создание в моделях? Поскольку я новичок в django, мне трудно понять тонкость вызовов функций.

1 Ответ

1 голос
/ 08 апреля 2020

Вы просите создать вложенный сериализатор с возможностью записи, когда у вас глубина 2, т.е. два вложенных сериализатора. К счастью, вы уже написали код в LaboratoireSerializer, который создает объекты Laboratoire и Tutelle на основе validated_data, поэтому вы можете сделать это:

class BGESSerializer(serializers.ModelSerializer):  

    class Meta:
        model = Laboratoire
        fields = '__all__'
        depth = 2

    def create(self, validated_data):
        laboratoire_data = validated_data.pop('laboratoire')
        laboratoire_obj = LaboratoireSerializer.create(self, laboratoire_data)  # note we don't instantiate the serializer! 
        validated_data["laboratoire"] = laboratoire_obj  # note we pass the object not pk
        bges = BGES.objects.create(**validated_data)
        return bges

Хитрость заключается в том, чтобы вызовите метод create для класса, передав ему self. Он работает, потому что метод create на самом деле не заботится о self и не использует его. Я бы не работал, если бы self использовался в create методе LaboratoireSerializer и ожидался бы LaboratoireSerializer. Я знаю, что это безрассудно, но работает.

...