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

Posted

技术标签:

【中文标题】如何保存具有关系的modelSerializer? - django【英文标题】:How to save a modelSerializer that has relations? - django 【发布时间】:2018-02-17 10:12:02 【问题描述】:

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

下面的 sn-p 是我的模型:

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() 方法默认不支持可写嵌套字段。 为序列化器mainp.serializers.KlassSerializer 写一个显式的.create() 方法,或者在嵌套的序列化器字段上设置read_only=True

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

【问题讨论】:

只覆盖KlassSerializer中ModelSerializer的create方法 我试图覆盖 create 方法,但我不能。你能告诉我怎么写吗?谢谢 【参考方案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)

【讨论】:

谢谢亲爱的 Hosein,它成功了,但我想将包括教师姓名和头像在内的 klass 数据发送到应用程序。您的回答解决了在数据库中保存数据的问题,但是现在我该如何发送老师的数据??谢谢 欢迎您,您可以为 get 方法定义单独的序列化程序并返回您想要的所有内容,如果上述答案正确,请批准并检查它是否正确【参考方案2】:

只需重写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
            ...

【讨论】:

我想保存一个从 json 获取教师值的 Klass 实例,而不是创建一个新的 Profile 实例。如何创建 Klass 实例??

以上是关于如何保存具有关系的modelSerializer? - django的主要内容,如果未能解决你的问题,请参考以下文章

如何保存具有直通关系的多对多字段

ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

drf--ModelSerializers序列化

如何在模板中显示具有外键关系的元素?

如何使用 ModelSerializer 显示所有模型字段?

Django Rest Framework - 如何在 ModelSerializer 中添加自定义字段