Django 1.11:能否在应用的DetailView中展示关联模型的数据?
在Django 1.11的DetailView中展示关联模型数据
当然可以实现!不管是从Journal/Product模型正向关联到rate应用的模型,还是反过来从rate的模型反向关联到Journal和Product,都能在DetailView对应的模板里轻松展示关联数据。下面分场景给你具体示例:
场景1:在Journal/Product的DetailView中展示关联的Rate数据
假设你的Journal模型里关联Rate的外键字段叫rate(比如rate = models.ForeignKey('rate.Rate', ...)),那实现起来非常简单:
1. 定义DetailView视图
# journal/views.py from django.views.generic.detail import DetailView from .models import Journal class JournalDetailView(DetailView): model = Journal template_name = 'journal/journal_detail.html' # 替换成你实际的模板路径
2. 在模板中访问关联数据
直接通过object.外键字段名就能拿到关联的Rate对象,然后展示它的字段:
<!-- journal/journal_detail.html --> <h1>{{ object.name }}</h1> <div class="related-rate"> <h3>关联的费率信息</h3> <p>费率名称:{{ object.rate.name }}</p> <!-- 这里可以继续展示Rate模型的其他字段,比如费率值、描述等 --> </div>
Product的DetailView实现逻辑完全一样,只需要把模型和模板路径换成对应的即可。
场景2:在Rate的DetailView中展示关联的所有Journal和Product
如果要在Rate的详情页展示所有关联的Journal和Product,需要用到反向关联。Django默认会为ForeignKey生成反向关联的集合,比如journal_set和product_set,你也可以在定义ForeignKey时通过related_name自定义名称(更推荐,可读性更强):
1. 优化模型的ForeignKey定义(可选但推荐)
# journal/models.py class Journal(models.Model): name = models.CharField(_('Name'), max_length=255) # 自定义反向关联名称为journals rate = models.ForeignKey('rate.Rate', on_delete=models.CASCADE, related_name='journals') # ...其他字段 # product/models.py class Product(models.Model): name = models.CharField(_('Name'), max_length=255) # 自定义反向关联名称为products rate = models.ForeignKey('rate.Rate', on_delete=models.CASCADE, related_name='products') # ...其他字段
2. 定义Rate的DetailView视图
# rate/views.py from django.views.generic.detail import DetailView from .models import Rate class RateDetailView(DetailView): model = Rate template_name = 'rate/rate_detail.html' # 可选:预取关联数据,避免N+1查询问题 def get_queryset(self): return Rate.objects.prefetch_related('journals', 'products')
3. 在模板中遍历关联的集合
通过自定义的related_name(或默认的xxx_set)就能拿到所有关联的Journal和Product:
<!-- rate/rate_detail.html --> <h1>{{ object.name }}</h1> <div class="related-journals"> <h3>关联的期刊列表</h3> <ul> {% for journal in object.journals.all %} <li>{{ journal.name }}</li> {% empty %} <li>暂无关联期刊</li> {% endfor %} </ul> </div> <div class="related-products"> <h3>关联的产品列表</h3> <ul> {% for product in object.products.all %} <li>{{ product.name }}</li> {% empty %} <li>暂无关联产品</li> {% endfor %} </ul> </div>
小提示:优化数据库查询
如果担心关联数据导致多次数据库查询(N+1问题),可以在DetailView的get_queryset方法中用:
select_related:用于正向的一对一/一对多关联(比如Journal到Rate)prefetch_related:用于反向的一对多/多对多关联(比如Rate到Journal/Product)
这样能大幅提升页面加载效率哦!
内容的提问来源于stack exchange,提问作者Cam Shan
相关产品推荐
相关产品推荐

