简体   繁体   English

DRF - 覆盖序列化程序的创建方法但 is_valid 返回错误

[英]DRF - overwriten serializer's create method but the is_valid returns erros

I am currently figuring out how to make my post request update the data of the entry if the id already exists in the database:我目前正在弄清楚如果 id 已经存在于数据库中,如何让我的发布请求更新条目的数据:

I've overwriten serializer's create methods like this:我已经覆盖了序列化程序的创建方法,如下所示:

class AttributeValueSerializer(serializers.ModelSerializer):
    class Meta:
        model = AttributeValue
        fields = ("id", "hodnota")

    def create(self, validated_data):
        id = validated_data.get('id')
        instance = AttributeValue.objects.filter(id=id).first()
        if instance:
            for key, value in validated_data.items():
                setattr(instance, key, value)
            instance.save()
            return instance
        return super().create(validated_data)

But the view which calls the serializer:但是调用序列化器的视图:

serializer = AttributeValueSerializer(data=item[key], partial=True)
if serializer.is_valid():
   serializer.post()
else:
   print(serializer.errors)

returns an error {'id': [ErrorDetail(string='attribute value with this id already exists.', code='unique')]} I am not sure what should I be doing here.返回错误{'id': [ErrorDetail(string='attribute value with this id already exists.', code='unique')]}我不确定我应该在这里做什么。 Should I somehow overwrite the is_valid method?我应该以某种方式覆盖 is_valid 方法吗?

As a general rule, if you're using DRF's ModelViewSet and the ModelSerializer , you'd have separate routes for creation and for updates ( PATCH / PUT routes using the resource id), when speaking of regular REST APIs.作为一般规则,如果您使用 DRF 的ModelViewSetModelSerializer ,当谈到常规 REST API 时,您将有单独的创建和更新路由(使用资源 ID 的PATCH / PUT路由)。

If you're sticking to your approach, however, what you need to do is to explicitly declare the typing of your id field on your serializer.但是,如果您坚持自己的方法,则需要做的是在序列化程序上显式声明id字段的类型。 As is, DRF's ModelSerializer will infer the typing/ options of the field based on your model .照原样,DRF 的ModelSerializer根据您的 model 推断字段的类型/选项 Something like this (assuming your IDs are integer fields):像这样(假设您的 ID 是 integer 字段):

class AttributeValueSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    class Meta:
        model = AttributeValue
        fields = ("id", "hodnota")

Making API is different in every case.在每种情况下制作 API 都是不同的。 I recommend to these two.我推荐给这两个。

  1. update_or_create更新或创建
  2. restfulAPI宁静API
class TempModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TempModel
        fields = (
            "id",
            "something",
        )

    def create(self, validated_data):
        instance, created = TempModel.objects.update_or_create(**validated_data)
        return instance

I think you can create more restful code for project.我认为您可以为项目创建更安静的代码。 Restful logic, in my opinion, is using various APIs on the frontend.(Case by case)在我看来,Restful 逻辑是在前端使用各种 API。(具体情况具体分析)

  1. find the data exists by using GET(List) Method on FrontEnd.通过在前端使用 GET(List) 方法查找数据是否存在。

    2-1. 2-1. If not exists Use POST(Create)如果不存在使用 POST(创建)

    2-2. 2-2。 Else PUT/PATCH(Update)否则 PUT/PATCH(更新)

Use this用这个

Mixins(ListModelMixin, CreateModelMixin, UpdateModelMixin) 

in your GenericView or ViewSet.在您的 GenericView 或 ViewSet 中。

Use serializer_class better right this.使用 serializer_class 更好地解决这个问题。

serializer_class = TempModelSerializer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM