【问题标题】:required=False not working with update_or_create in ModelSerializerrequired=False 不适用于 ModelSerializer 中的 update_or_create
【发布时间】:2019-09-13 11:22:12
【问题描述】:

我正在创建一个 API,我在其中获取一些带有 user_id 字段的数据。如果数据库中存在给定的 user_id,它将更新其余数据,否则它将创建新数据。这是我的代码:

serializers.py

class DataUpdateSerializer(serializers.ModelSerializer):
    user_id = serializers.CharField(max_length=250)
    email = serializers.EmailField(required=False)
    first_name = serializers.CharField(required=False)
    last_name = serializers.CharField(required=False)

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'user_id', 'balance', 'device_id', 'platform')

    def create(self, validated_data):
        data_update, created = User.objects.update_or_create(user_id=validated_data['user_id'],
                                                          defaults={
                                                              'first_name': validated_data['first_name'],
                                                              'last_name': validated_data['last_name'],
                                                              'email': validated_data['email'],
                                                              'balance': validated_data['balance'],
                                                              'device_id': validated_data['device_id'],
                                                              'platform': validated_data['platform'],

                                                          }
                                                          )

        return data_update

views.py

class data_update(APIView):

    permission_classes = (Check_API_KEY_Auth,)

    def post(self, request):
        serializer = DataUpdateSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            username = request.data['user_id']
            User.objects.filter(user_id=username).update(username=username)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_204_NO_CONTENT)

email、first_name 和 last_name 是可选的,在 DB 或序列化程序中可以为空。

Models.py

class User(AbstractUser):
    device_id = models.CharField(max_length=250)
    balance = models.FloatField()
    platform = models.CharField(max_length=250)
    user_id = models.CharField(max_length=250, unique=True)

问题:

一切正常,但如果我不传递电子邮件、名字或姓氏,它会给出错误:key_error,如果我为这些字段提供空白值“”,这个给出的错误不能为空白

【问题讨论】:

  • 用户模型中的 email、first_name 和 last_name 字段是否有 blank=True?
  • 我已经扩展了 django 默认用户模型,我没有对现有字段进行任何更改。
  • 你能添加那个模型吗?
  • models.py 添加。请检查

标签: django django-rest-framework


【解决方案1】:

我在您的代码中发现了各种问题。

  • 在模型中 CharField 的声明中,你没有blank=True。因此,无论您在上面做什么,它们都不能在数据库中为空白。

  • 在使用非常基本的APIView 并自己操作序列化程序时要小心。您的视图称为“更新”,但它同时执行“创建”和“更新”。这是两件不同的事情,通常由两条不同的路线处理。

  • 您对序列化程序 DataUpdateSerializer(data=request.data) 的使用是用于 CREATE,而不是 UPDATE,您将相关模型对象的实例作为第一个参数传递。

  • 必须检查您对objects.update_or_create 的使用情况。您基本上使用可能存在或不存在的字段进行查询集过滤,其值可能已更改或未更改,并且如果过滤有任何意义,并且您没有得到任何回报,那么您创建对象。 ..

我建议拆分路线。在您可以创建的地方创建一个ListAPIView,并在您的 REST 路由中创建一个将user_id 作为参数的RetrieveUpdateDestroyAPIView,并在视图中简单地声明序列化程序类。然后,使用序列化程序本身的createupdate 方法。但是,如果所有内容都只是简单地声明,那么您几乎不需要在这些方法中编写任何内容。

【讨论】:

  • 我知道我应该使用 create 和 update 但是我将不得不为这两种情况使用 post 和 patch/put 方法。如果用户已经存在,则数据源不会。源如何知道在请求中发送哪种方法。
  • 这就是解耦数据及其消耗的生命周期。使用未知用户名点击您的端点 -> 404,好的 -> 使用列表端点创建...
  • 正式检查一个资源是否存在是一个请求的作用,更新一个资源是另一个。每个都有其一致的响应代码来解释发生了什么。
猜你喜欢
  • 2019-06-07
  • 2016-01-05
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 2014-02-26
  • 2019-01-25
  • 2014-07-04
相关资源
最近更新 更多