【问题标题】:(Django REST) Override Non-Editable Field in the (Views) `create` Method(Django REST)覆盖(视图)`create`方法中的不可编辑字段
【发布时间】:2019-07-19 12:59:46
【问题描述】:

在我的models.py 中,我创建了一个用户不可编辑的字段:

request_status = models.CharField(
    max_length = 100,
    default = 'received', 
    editable = False
)

views.py 文件中,我重写create() 方法(来自generics.ListCreateAPIViewCreateModelMixin 超类)来激活一个docker 容器,如果成功完成,我想修改request_status字段到 container_activated 之类的内容,然后将 HTTP 响应发回给用户。

那么...有没有办法修改不可编辑的字段?有没有更好的方法来设置model

我最好的猜测是,有一种方法可以通过标准 create() 方法的其中一行来修改在 API DB 中注册的数据(不可编辑的字段不会出现在 data 属性中) :

serializer = self.get_serializer(data = request.data)
serializer.is_valid(raise_exception = True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    editable=False 并不意味着您根本无法编辑该字段,它仅意味着默认情况下它不会显示在管理员或模型表单中。在 DRF 中,表示会自动设置为read_only;但是您可以简单地手动定义字段来覆盖它。

    class MySerializer(serializers.ModelSerializer):
        request_status = serializers.CharField(max_length=100, default='received')
        class Meta:
            ...
    

    【讨论】:

    • 但是每次数据被序列化时都会覆盖序列化器中的字段,而我想要的是每当成功执行特定操作时更改该字段,例如,创建一个泊坞窗容器 --- 我认为这应该发生在 views.py create() 方法中。不应该吗?
    【解决方案2】:

    这是一种规避,但它或多或少地运作良好。我将我的字段改回editable = True,然后我只是将其强制为默认锁定(硬编码)值。最后,在 views.py 类的 create() 中,您可以输入如下内容:

    def create(
        self, 
        request, 
        *args, 
        **kwargs
    ):
    
        # Settings of the POST request
        req_data = request.data.dict()
        req_data['request_status'] = 'not yet processed'
    
        # Is everything OK?
        if processing_OK == 0:
            req_data['request_status'] = 'processed'
    
        # Save the data
        serializer = self.get_serializer(data = req_data)
        serializer.is_valid(raise_exception = True)
        serializer.save() # `self.perform_create(serializer)` originally
        headers = self.get_success_headers(serializer.data)
    
        # Return Response
        return Response(
            data = serializer.data,
            status = status.HTTP_201_CREATED, 
            headers = headers
        )
    

    关键部分是了解您可以通过更改 request.data.dict() 中的字典来覆盖 API 内的 HTTP POST 中的内容。然后你只需在self.get_serializer() 中传递那个dict(实际上通常是QueryDict)并遵循标准的create() 方法。

    如果您配置editable = False,您将无法按照我在此处发布的方式强制进行更改。最终可能会有更好的方法来做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      相关资源
      最近更新 更多