代码之家  ›  专栏  ›  技术社区  ›  Fomalhaut

如何在Django REST框架中使字段在创建时可编辑,在更新时只读

  •  1
  • Fomalhaut  · 技术社区  · 6 年前

    1 回复  |  直到 6 年前
        1
  •  10
  •   F.M.F.    5 年前

    覆盖序列化程序中的更新方法并删除字段:

    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)
    
        2
  •  1
  •   Peza    3 年前

    上述两种解决方案都有效,但创建可扩展方法以控制任何CRUD操作的修改权限的一种好方法如下:

    1. 创建基序列化程序类: BaseSerializer
    2. 在所有序列化程序类中从该类继承

    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 为了答案!