You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:48:03