【问题标题】:How to save a modelSerializer that has relations? - django如何保存具有关系的modelSerializer? - 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 方法,但我不能。你能告诉我怎么写吗?谢谢

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


【解决方案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 实例??
猜你喜欢
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-03-19
  • 2019-06-16
  • 1970-01-01
  • 2017-05-17
  • 2021-08-18
  • 1970-01-01
相关资源
最近更新 更多