如何在Django Admin的Detail表单中直接显示Info模型的所有字段?
在Django Admin中嵌入关联模型字段替代外键选择
实现方案
通过自定义表单与重写Admin的保存逻辑,就能把Info模型的字段直接作为普通表单字段展示在Detail的添加/编辑页面中,替代默认的外键选择框。
1. 自定义Detail管理表单
在admin.py中定义继承自ModelForm的自定义表单,添加Info模型的字段,并排除原有的外键字段:
from django import forms from .models import Detail, Info class DetailAdminForm(forms.ModelForm): # 添加Info的字段作为表单普通字段 first_name = forms.CharField(max_length=100) last_name = forms.CharField(max_length=100) class Meta: model = Detail exclude = ['info'] # 隐藏原外键选择字段 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 编辑已有Detail时,自动填充关联Info的字段值 if self.instance.pk and self.instance.info: self.fields['first_name'].initial = self.instance.info.first_name self.fields['last_name'].initial = self.instance.info.last_name
2. 配置Detail的Admin类
使用自定义表单,并重写save_model方法处理Info对象的创建/更新与关联:
from django.contrib import admin @admin.register(Detail) class DetailAdmin(admin.ModelAdmin): form = DetailAdminForm def save_model(self, request, obj, form, change): first_name = form.cleaned_data.get('first_name') last_name = form.cleaned_data.get('last_name') if change and obj.info: # 编辑模式:更新已关联的Info对象 obj.info.first_name = first_name obj.info.last_name = last_name obj.info.save() else: # 新增模式:创建或复用匹配的Info对象 info_obj, _ = Info.objects.get_or_create( first_name=first_name, last_name=last_name ) obj.info = info_obj # 保存Detail实例 super().save_model(request, obj, form, change)
效果说明
- 新增Detail时:页面显示
first_name、last_name等普通输入框,提交后会自动创建(或复用已有)Info对象并关联到当前Detail。 - 编辑Detail时:输入框会自动填充已关联Info的字段值,修改提交后会同步更新对应的Info对象。
内容的提问来源于stack exchange,提问作者rudra
相关产品推荐
相关产品推荐

