【问题标题】:Override django serializer or models create method覆盖 django 序列化程序或模型创建方法
【发布时间】:2020-04-08 14:47:50
【问题描述】:

我正在尝试将数据添加到我的数据库中。为此目的,我有一个 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 类也是嵌套的,应该添加其他类的实例:

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

这是行不通的,因为它是序列化程序的创建而不是模型的创建而不是调用。 我应该怎么做 ?当我添加一个实验室时,我有 Tutelle 来创建......我应该在模型中实现创建吗?由于我是 django 新手,我很难理解函数调用的微妙之处。

【问题讨论】:

标签: django django-models django-rest-framework django-serializer


【解决方案1】:

当深度为 2 时,您要求创建一个可写的嵌套序列化器,即两个嵌套序列化器。幸运的是,您已经在LaboratoireSerializer 中编写了基于validated_data 创建LaboratoireTutelle 对象的代码,因此您可以这样做:

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 并且不使用它。如果在LaboratoireSerializercreate 方法中使用了self 并且预期是LaboratoireSerializer,我将无法工作。我知道这很 hacky,但它确实有效。

【讨论】:

  • 谢谢你,我还是不明白,为什么 django 从嵌套对象中删除 pk 键。在validated_data 中,我不再有来自LaboratoiresSerializer.create 函数的pk 值,所以我无法获得tutelles id。有什么想法吗?
  • 也许添加depth = 2?但经过验证的数据应该包含实际实例,而不是 pks。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 2018-01-09
相关资源
最近更新 更多