Django Admin多模型关联动态显示与模板遍历实现问询
Django 实现动态展示子模型表格及模板遍历关联数据方案
一、Admin 后台动态展示对应子模型表格
1. 定义子模型的 Inline 类
先为每个子模型创建对应的 Inline 类,用于在 Resume 编辑页展示子模型的数据表格:
from django.contrib import admin from .models import Resume, Summary, Education, Experience class SummaryInline(admin.TabularInline): model = Summary extra = 1 classes = ['inline-summary'] # 用于JS匹配的CSS类 class EducationInline(admin.TabularInline): model = Education extra = 1 classes = ['inline-education'] class ExperienceInline(admin.TabularInline): model = Experience extra = 1 classes = ['inline-experience']
2. 针对已保存 Resume 动态加载 Inline
在 ResumeAdmin 中重写 get_inlines 方法,根据已保存对象的 category 值返回对应 Inline:
class ResumeAdmin(admin.ModelAdmin): fields = ['category', 'name', ...] # 你的其他Resume字段 def get_inlines(self, request, obj=None): inlines = [] if obj: # 仅编辑已存在对象时生效 if obj.category == 'summary': inlines = [SummaryInline] elif obj.category == 'education': inlines = [EducationInline] elif obj.category == 'experience': inlines = [ExperienceInline] return inlines
3. 新增 Resume 时前端动态切换 Inline
如果需要在新增 Resume 时,选择 category 后实时切换展示对应的子模型表格,需添加自定义 JS:
首先在 ResumeAdmin 中引入 JS 文件:
class ResumeAdmin(admin.ModelAdmin): # 其他配置... class Media: js = ('admin/js/resume_category_switch.js',)
然后在 static/admin/js/resume_category_switch.js 中编写逻辑:
document.addEventListener('DOMContentLoaded', function() { const categorySelect = document.getElementById('id_category'); const inlineGroups = document.querySelectorAll('.inline-group'); // 初始隐藏所有Inline inlineGroups.forEach(group => group.style.display = 'none'); // 根据选中的category显示对应Inline function toggleInlines() { const selectedCat = categorySelect.value; inlineGroups.forEach(group => { group.style.display = group.classList.contains(`inline-${selectedCat}`) ? 'block' : 'none'; }); } // 监听选择变化+初始化执行 categorySelect.addEventListener('change', toggleInlines); toggleInlines(); });
二、模板中遍历关联子模型数据
Django 中外键的反向关联默认命名为 模型名小写_set,你可以根据关联类型的不同,用以下方式遍历:
1. 一对多关联(如 Resume ↔ Experience)
如果 Experience 模型通过 ForeignKey 关联 Resume:
class Experience(models.Model): resume = models.ForeignKey(Resume, on_delete=models.CASCADE) # 其他字段:title、company、start_date等
模板中遍历写法:
{% for experience in resume.experience_set.all %} <div class="experience-item"> <h3>{{ experience.title }}</h3> <p>{{ experience.company }} | {{ experience.start_date }} - {{ experience.end_date }}</p> <p>{{ experience.description }}</p> </div> {% empty %} <p>暂无工作经历</p> {% endfor %}
2. 自定义反向关联名称
如果在 ForeignKey 中设置了 related_name:
class Experience(models.Model): resume = models.ForeignKey(Resume, on_delete=models.CASCADE, related_name='experiences')
模板中可以直接用自定义名称遍历:
{% for exp in resume.experiences.all %} <!-- 展示内容 --> {% endfor %}
3. 一对一关联(如 Resume ↔ Summary)
如果是 OneToOneField 关联,直接通过属性获取即可,无需遍历:
{% if resume.summary %} <div class="summary"> <p>{{ resume.summary.content }}</p> </div> {% else %} <p>暂无个人简介</p> {% endif %}
内容的提问来源于stack exchange,提问作者Nugget
相关产品推荐
相关产品推荐

