如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?
Posted
技术标签:
【中文标题】如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?【英文标题】:How to display multiple ForeignKey filtered items in a single view in django? 【发布时间】:2016-01-15 05:25:03 【问题描述】:我试图了解在 Django 模型中显示 ForeignKey
过滤数据的最佳方式。
我将三个模型简化为:
// models.py
class Publisher(models.Model)
def publisher_name = models.TextField()
def publisher_slug = models.SlugField()
def founded_year = models.IntegerField()
class Album(models.Model)
def album_name = models.TextField()
def publisher = models.ForeignKey('Publisher', related_name='albums')
class Song(models.Model)
def song_name = models.TextField()
def album = models.ForeignKey('Album', related_name='songs')
def published_year = models.IntegerField()
我有一个由以下内容组成的 URL:/<publisher>/<published_year>/
我在撰写时遇到问题的视图应该是这样的细节:
标题:Publisher.publisher_name 出版商的所有专辑列表:该专辑中与出版商同年出版的所有歌曲列表__published_year:该专辑中作为网址发布的所有歌曲列表
我现在尝试这样做的方式与此类似:
// views.py
class SongYearView(TemplateView):
def get_context_data(self, **kwargs):
context = super(SongYearView, self).get_context_data(**kwargs)
context['publisher'] = Publisher.objects.get(slug=kwargs['publisher_slug']
album_list=[]
for album in context['publisher'].albums.all():
single_album = dict()
single_album['album'] = album
single_album['publisher_year_song'] = album.songs.filter(published_year=context['publisher'].published_year)
single_album['filtered_year_song'] = album.songs.filter(published_year=kwargs['published_year']
album_list.append(single_album)
context['albums'] = album_list
return context
然后在我正在做的模板中(去除格式)
// template.html
publisher.name
% for album in albums %
album.album.album_name
% for song in album.publisher_year_song %
song.song_name
% endfor %
% for song in album.filtered_year_song %
song.song_name
% endfor %
% endfor %
虽然这确实有效,但它并不漂亮,我很确定有更好的方法来做到这一点。
这是一个奇怪的例子,但只是我更详细模型的一个基本例子。考虑它的方式是出版商->专辑->歌曲或A->B->C。我试图查看所有B项目,这些项目只与特定的A项目链接,然后得到两个每个 B 项的 C 项集合,其中一组根据 A 属性过滤,另一组根据来自 URL 的传递参数进行过滤。
我试图获得一个自定义 model.Manager 来帮助构建它,但运气不佳。
【问题讨论】:
我想知道这是否应该更好地放在Code review 啊,我不知道代码审查部分。这个查询更多地表明我已经尝试了一些东西,但我想知道编程场景的正确方法。 由于您的代码工作正常,它完全符合代码审查指南,但您的说明可能要少得多......(我认为,在 SO 上发布它仍然很好) 我重命名了模板过滤器:我觉得这样更好。 (如果我的回答解决了您的问题,请将其标记为已接受 - 检查箭头附近) 【参考方案1】:你可以做add a custom template filterof_year
:
@register.filter
def of_year(songs, year):
return songs.filter(published_year=year)
并将您的模板更改为
// template.html
publisher.name
% for album in publisher.albums %
album.album.album_name
% for song in album.songs|of_year:publisher.founded_year %
song.song_name
% endfor %
% for song in album.songs|of_year:filtered_year %
song.song_name
% endfor %
% endfor %
并清理您的视图:
// views.py
class SongYearView(TemplateView):
def get_context_data(self, **kwargs):
context = super(SongYearView, self).get_context_data(**kwargs)
context['publisher'] = Publisher.objects.get(slug=kwargs['publisher_slug'])
context['filtered_year'] = kwargs['published_year']
return context
编辑:重命名模板过滤器
【讨论】:
以这种方式使用过滤器是正确的方法吗?这不是通过自定义模型管理器更好地处理吗?正如我所读到的,模板应该避免使用功能。 我在 django 方面做得不够好,无法通过自定义模型管理器来处理它。As I've read that the templates should avoid functionality.
我确实同意这个观点,我认为在你的情况下,过滤更多地与演示文稿(模板)有关,而不是模型(我试图将我的过滤器限制为一个额外的参数和 2 行代码) 以上是关于如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?的主要内容,如果未能解决你的问题,请参考以下文章
Django 表单:查询结果定义的字段,单个视图同时更新多个对象
我可以在 django 中的单个表单中使用多个表单集,如果可以的话如何?
有没有一种方法可以在 Django 的同一个模板中呈现多个视图?