如何实现Django模型字段创建时可编辑,已有对象只读?
Django模型id创建后只读、创建时可自定义的实现方案
- 如果你需要全局所有场景都生效的限制(后台、表单、API等所有调用保存逻辑的场景),直接在模型层加校验逻辑即可,完整代码如下:
import uuid from django.db import models from django.core.exceptions import ValidationError class Vehicle(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) def clean(self): # 非新增场景校验id是否被修改 if self.pk is not None: original_obj = Vehicle.objects.filter(pk=self.pk).first() if original_obj and original_obj.id != self.id: raise ValidationError("id字段创建完成后不可编辑") super().clean() def save(self, *args, **kwargs): # 强制触发校验,避免部分场景跳过clean方法 self.full_clean() super().save(*args, **kwargs)
该方案会在任何尝试修改已存储实例id的操作时抛出错误,同时保留创建时传入自定义id的能力。
- 如果你仅需要在Django Admin后台限制编辑,无需全局拦截,可直接配置Admin类的只读字段判断逻辑:
from django.contrib import admin from .models import Vehicle @admin.register(Vehicle) class VehicleAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): # 编辑已有实例时将id设为只读,新增页保持可编辑 if obj: return (*self.readonly_fields, 'id') return self.readonly_fields
- 如果你使用Django REST Framework开发接口,仅需要在接口层做限制,可在序列化器中添加校验逻辑:
from rest_framework import serializers from .models import Vehicle class VehicleSerializer(serializers.ModelSerializer): class Meta: model = Vehicle fields = "__all__" def validate_id(self, value): if self.instance and self.instance.id != value: raise serializers.ValidationError("id字段创建完成后不可编辑") return value
内容的提问来源于stack exchange,提问作者sudeepdino008
相关产品推荐
相关产品推荐

