如何在django中的单个视图中显示多个ForeignKey过滤项?

时间:2015-10-16 12:43:15

标签: python django django-models django-templates django-views

我试图了解在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()

我有一个由以下网址组成的网址:/<publisher>/<published_year>/

我在撰写时遇到问题的观点应该是这样的细节:

标题:Publisher.publisher_name 出版商的所有专辑列表:该出版物同年出版的所有歌曲列表出版商_出版年份:该专辑中所有歌曲列表作为网址发布

我现在试图这样做的方式类似于:

// 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 %}

虽然这确实有效,但它并不漂亮,而且我非常确定有更好的方法可以做到这一点。

这是一个奇怪的例子,但只是我更详细模型的一个基本例子。考虑它的方式是Publisher - &gt;专辑 - &gt;歌曲或A - &gt; B - &gt; C.我试图查看所有B项目的视图,这些项目仅与特定A项目链接,然后为每个B项目获取两组C项目,其中一组在A属性上过滤,另一个集对来自URL的传递参数进行过滤。

我试图获得一个自定义的model.Manager来帮助构建它,但没有多少运气。

1 个答案:

答案 0 :(得分:1)

您可以执行add a custom template filter of_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

编辑:重命名模板过滤器