如何保存有关系的 modelSerializer? - 姜戈

How to save a modelSerializer that has relations? - django

我想通过 django-rest-framework 将发送的 json 数据保存到数据库。 问题是,没有保存关系和 returns 错误。

下面的片段是我的模型:

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE)
    name = models.CharField(max_length=30)
    family = models.CharField(max_length=50)

class Klass(models.Model):
    title = models.CharField(max_length=50)
    description = models.CharField(max_length=500)
    teacher = models.ForeignKey(Profile, related_name='teacher', on_delete=models.CASCADE)

我为 serializing/deserializing Klass 模型使用下面的序列化程序。

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ('pk', 'name', 'family')

class KlassSerializer(serializers.ModelSerializer):
    teacher = ProfileSerializer()        

    class Meta:
        model = Klass
        fields = ('id', 'title', 'description', 'teacher')

现在,当我准备一个 JSON 对象并将其发送到视图时,它 returns 出错。下面是视图 class:

class KlassView(APIView):
"""for SELECT, INSERT Queries"""

    def get(self, request, pk):
         # somthing

    @csrf_exempt
    def post(self,request, pk=None):
        """For Creating A Class"""
        serializer = KlassSerializer(data=request.data)
        if serializer.is_valid():
            teacher = ProfileSerializer(request.data['teacher']['pk'])
            serializer.teacher = teacher.data            
            serializer.save()
            return Response({'data': serializer.data})
        else:
            return Response({'data': serializer.errors})

错误是:

The .create() method does not support writable nested fields by default. Write an explicit .create() method for serializer mainp.serializers.KlassSerializer, or set read_only=True on nested serializer fields.

如何在 KlassSerializer 中保存关系以便保存到数据库?

重写KlassSerializer中ModelSerializer的create方法即可

class KlassSerializer(serializers.ModelSerializer):
    teacher = ProfileSerializer()        

    class Meta:
        model = Klass
        fields = ('id', 'title', 'description', 'teacher')

    def create(self, validated_data):
        profile = Profile.objects.filter(pk=validated_data['teacher']['pk'])
        if profile:
            k = Klass()
            k.teacher = profile
            ...

首先像下面这样改变你的序列化器:

class KlassSerializer(serializers.ModelSerializer):
    # teacher = ProfileSerializer() # No need to this!

    class Meta:
        model = Klass
        # fields = ('id', 'title', 'description', 'teacher')
        fields = ('id', 'title', 'description') # Omit teacher

然后从请求的用户处获取配置文件并将其传递给您的序列化程序:

    def post(self,request, pk=None):
    """For Creating A Class"""
    serializer = KlassSerializer(data=request.data)
    if serializer.is_valid():
        teacher = ProfileSerializer(request.data['teacher']['pk'])
        serializer.teacher = teacher.data            
        serializer.save(teacher=request.user.profile) # Retrieve teacher and stroe 
        return Response({'data': serializer.data})
    else:
        return Response({'data': serializer.errors})