Django objects.filter在模板中

时间:2018-05-07 18:37:46

标签: python django django-templates

我有django项目,有三个以下型号:

models.py
from django.db import models
from django.contrib.auth.models import User


class Album(models.Model):
    owner = models.ForeignKey(User)
    title = models.CharField(max_length=127)
    artist = models.CharField(max_length=63)
    release_date = models.DateField()
    logo = models.ImageField(blank=True, upload_to='album_logos', default='album_logos/no-image.jpeg')
    t_added = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(null=True, blank=True, max_length=63)

    class Meta:
        ordering = ['-release_date']

    def __str__(self):
        return self.title


class Song(models.Model):
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    # is_favorite = models.BooleanField(default=False)
    favorites = models.IntegerField(default=0)
    song_file = models.FileField(blank=True, null=True, upload_to='song_files', default='song_files/mektub.mp3')

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name


class Favorite(models.Model):
    user = models.ForeignKey(User)
    song = models.ForeignKey(Song)
    created = models.DateTimeField(auto_now_add=True)

从这些模型中可以看出,许多用户可以收藏很多歌曲。在模板中,我想将类添加到经过身份验证的用户收藏的歌曲中:

template
<span {% if authenticated user favorited this song %}class="favorited" {% endif %}></span>

我的问题是,我不知道怎么写#34;如果经过验证的用户喜欢这首歌&#34;在模板中。在终端中,我可以通过以下代码获取此信息:

user_favorited_this = song.favorite_set.filter(user=sample_user) and True or False

我无法在模板中执行相同的操作,因为它不支持将参数传递给filter方法。我怎样才能克服这个问题?

2 个答案:

答案 0 :(得分:1)

标签过滤器可以执行您想要的操作:
如果User.favorite_set.allSong.favorite_set.all有共同点,则表示当前用户已收藏该歌曲

from django import template
register = template.Library()

# Method 1 for django queryset (Better)
@register.filter    
def intersection(queryset1,queryset2):
    return queryset1 & queryset2

# Method 2 for queryset or python List
@register.filter
def intersection(queryset1,queryset2):
    return list(set.intersection(set(queryset1),set(queryset2)))

HTML:

{% if request.user.favorite_set.all|intersection:song.favorite_set.all %} class="favorited" {% endif %}

答案 1 :(得分:0)

在视图中执行此操作可能更简单,然后将结果作为布尔标志传递给模板。

例如:

def song_view(request):
    ...
    song = Song.objects.get(pk=request.GET['song_id'])
    is_favorite = song.favorite_set.filter(user=request.user).exists()
    return render(request, 'my_template.html', {'is_favorite': is_favorite})

或基于通用类的视图:

class SongDetail(DetailView):
    ...
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        song = self.get_object()
        is_favorite = song.favorite_set.filter(user=self.request.user).exists()
        context['is_favorite'] = is_favorite
        return context

然后模板中的代码可以简化为:

<span {% if is_favorite %}class="favorited" {% endif %}></span>