我想实现一种Django模型的常量字段。我希望在创建模型实例(通过REST框架API)时设置该字段,但是在更新时必须禁止更改该字段。在Django本身或REST框架序列化器选项中,是否有一种优雅的方法?
答案 0 :(得分:2)
覆盖序列化程序中的更新方法并删除字段:
class MySerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
validated_data.pop('myfield', None) # prevent myfield from being updated
return super().update(instance, validated_data)
答案 1 :(得分:1)
上述两种解决方案都有效,但创建可扩展方法来控制任何 CRUD 操作的修改权限的好方法如下:
BaseSerializer
基本序列化器类中的控件:
class BaseSerializer(DynamicFieldsSerializer):
# This overrides a built-in base class method
def get_extra_kwargs(self):
"""Add additional constraints between CRUD methods to
any particular field
NB: Use the same extra_kwags dict object in all method calls
- important to make changes on central object
"""
extra_kwargs_for_edit = super().get_extra_kwargs()
# Example of making uuid only editable on create, not update
self.add_create_only_constraint_to_field("uuid", extra_kwargs_for_edit)
return extra_kwargs_for_edit
def add_create_only_constraint_to_field(self, key: str, extra_kwargs: dict) -> dict:
"""Ensures key is only writable on create, not update"""
action = self.context["view"].action
if action in ["create"]:
kwargs = extra_kwargs.get(key, {})
kwargs["read_only"] = False
extra_kwargs[key] = kwargs
elif action in ["update", "partial_update"]:
kwargs = extra_kwargs.get(key, {})
kwargs["read_only"] = True
extra_kwargs[key] = kwargs
# You could add other constraints to CRUD operations here
# def another_field_constrained_by_crud_method(self, key: str, extra_kwargs: dict) -> dict:
class SomeModelSerializer(BaseSerializer):
# Your serializer logic here
pass
感谢 Nicholas Coles 的回答!
答案 2 :(得分:0)
将序列化程序的 __init__()
方法替换为,
class MySerializer(serializers.ModelSerializer):
myfield = serializers.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context['view'].action == 'create':
self.fields['myfield'].write_only = True