如何保存有关系的modelSerializer? - django

时间:2017-09-08 13:05:48

标签: django django-rest-framework django-orm django-rest-viewsets

我想通过django-rest-framework将发送的json数据保存到db。 问题是,不保存关系并返回错误。

波纹管片段是我的模特:

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)

我使用下面的序列化程序来序列化/反序列化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对象并将其发送到视图时,它会返回错误。以下是视图类:

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})

,错误是:

  

默认情况下,.create()方法不支持可写嵌套字段。   为序列化程序.create()编写明确的mainp.serializers.KlassSerializer方法,或在嵌套的序列化程序字段上设置read_only=True

如何保存KlassSerializer中的关系才能保存到数据库?

2 个答案:

答案 0 :(得分:1)

首先更改下面的序列化程序:

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})

答案 1 :(得分:0)

只需覆盖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
            ...