Django:使用列表中的项而不在视图中执行for循环

时间:2018-05-28 16:28:37

标签: django loops templates view

对于标题不清楚的道歉,我不知道如何用几句话来表达我的问题。

基本上,在我的视图中,我有一个包含对象列表的变量(照片):

photos = Photo.objects.all()

在我的模板中,我有一个for循环用于显示属性的这些对象(例如photo.author)。我想在个别照片实例上运行一些逻辑:

all_likes = Like.objects.all()
for photo in photos:
    pic_likes = all_likes.filter(photo_id=id)
    like_count = len(pic_likes)
    liker = pic_likes.filter(liker_id=request.user.id)
    if len(liker) != 0:
        liked=True

但在视图中使用for循环会导致错误

int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'

我应该如何为照片实例提供逻辑而不是整个对象列表呢?

我的照片模型如下:

class Photo(models.Model):
    image = models.ImageField(upload_to='uploaded_images', blank=True)
    title = models.CharField(max_length=128)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, default = 1)
    slug = models.SlugField()
    likes = models.ManyToManyField(User, related_name='likes')
    description = models.CharField(max_length=1000, blank=True)

和我喜欢的模型是:

class Like(models.Model):
    liker = models.ForeignKey(User, related_name='liker')
    photo = models.ForeignKey(Photo, related_name='photo')
    liked = models.BooleanField()

1 个答案:

答案 0 :(得分:1)

我建议您更改related_name模型中的Like属性,甚至可以删除它以使用默认名称:

class Like(models.Model):
    liker = models.ForeignKey(User)
    photo = models.ForeignKey(Photo)
    liked = models.BooleanField()

现在您可以像这样使用它:

all_likes_of_a_user = user_instance.like_set.all()
all_likes_of_a_photo = photo_instance.like_set.all()

现在,要迭代视图中的照片,您可以使用:

for photo in Photo.objects.all():
    like_count = photo.like_set.count()
    has_liked = photo.like_set.filter(liker=request.user).exists()

要在模板中使用它,您可以添加嵌套循环:

{% for photo in Photo.objects.all %}
    Like count: {{ photo.like_set.count }}
    Has this user liked this photo:
    {% for like in photo.like_set.all %}
        {% if like.liker == user %}
        yes
        {% endif %}
    {% endfor %}
{% endfor %}

或者为Photo模型添加方法:

class Photo(models.Model):
    ...
    def users_that_liked_it(self):
        return [
            e.liker.pk
            for e in self.like_set.all()]

{% for photo in Photo.objects.all %}
    Like count: {{ photo.like_set.count }}
    Has this user liked this photo:
    {% if user.pk in photo.users_that_liked_it %}
        yes
    {% else %}
        no
    {% endif %}
{% endfor %}