Django Admin中如何获取当前表单的ID
Django Admin 配置中获取当前操作表单对应ID的实现方式
首先明确前提:新增未保存的表单没有对应数据库ID,只有编辑已存在对象、或对象完成保存动作后才能拿到有效ID,不同开发场景下的获取方式如下:
- 在ModelAdmin自带的重写方法中获取
日常改字段配置、表单配置、保存逻辑的场景(比如重写get_fields、get_form、save_model、get_readonly_fields这些方法),方法本身会接收obj参数,编辑场景下obj就是当前操作的模型实例,直接取属性即可:from django.contrib import admin from .models import DemoModel class DemoModelAdmin(admin.ModelAdmin): # 举个动态控制只读字段的例子 def get_readonly_fields(self, request, obj=None): base_readonly = super().get_readonly_fields(request, obj) # 编辑状态下obj不为空,直接取id if obj and obj.id == 1: return base_readonly + ('name',) return base_readonly def save_model(self, request, obj, form, change): # change为True代表是编辑操作,保存前就有id if change: edit_target_id = obj.id super().save_model(request, obj, form, change) # 执行完save后,不管是新增还是编辑,obj一定带自增ID operated_id = obj.id - 在自定义ModelForm类中获取
如果是自定义表单类做字段校验、动态渲染逻辑,需要手动把实例ID从Admin层传到Form实例里:from django import forms from .models import DemoModel class DemoCustomForm(forms.ModelForm): class Meta: model = DemoModel fields = "__all__" def __init__(self, *args, **kwargs): # 从初始化参数里弹出提前传入的ID self.current_id = kwargs.pop('operate_obj_id', None) super().__init__(*args, **kwargs) # 拿到ID后可以写自定义表单逻辑,比如过滤关联字段的queryset if self.current_id: pass class DemoModelAdmin(admin.ModelAdmin): form = DemoCustomForm def get_form(self, request, obj=None, **kwargs): form_cls = super().get_form(request, obj, **kwargs) # 给表单类注入初始化参数 init_kwargs = getattr(form_cls, 'kwargs', {}) init_kwargs['operate_obj_id'] = obj.id if obj else None form_cls.kwargs = init_kwargs return form_cls - 在自定义Admin模板中获取
如果是重写admin的change_form模板做前端自定义,模板上下文默认自带object_id变量,直接在模板中调用{{ object_id }}就能拿到当前编辑对象的ID,不需要额外传参。如果是自己写的Admin自定义视图,把对应ID放到渲染上下文的object_id字段里即可。
踩坑提示:不要在请求刚进Admin、还没走到对象解析逻辑的时候硬从URL路径里截ID,不同版本Django的Admin路由规则可能有调整,用框架自带的参数拿实例是兼容性最高的写法。
内容的提问来源于stack exchange,提问作者yawoo elie
相关产品推荐
相关产品推荐

