【问题标题】:How to do I refer to a result of a function in a template? django如何在模板中引用函数的结果? django
【发布时间】:2016-06-26 11:45:42
【问题描述】:

我有这些模型:

# this is model for user
class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile')

    profilepic = models.ImageField(blank=True)


    city = models.ForeignKey(City)
    slug = models.SlugField(unique=True)


    def save(self, *args, **kwargs):
        self.slug = slugify(self.user.username)
        super(UserProfile, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.user.username

    @property
    def avg_rating(User):
        return UserProfile.userrating_set.all().aggregate(Avg('rating'))['rating__avg']


# this is the model for user ratings - one to many relationship with User
class UserRating(models.Model):
    user = models.ForeignKey(User)
    comment = models.CharField(max_length=500)
    for_username = models.CharField(max_length=128)
    rating = models.IntegerField(default=5)

    def __unicode__(self):
        return unicode(self.rating)

我想在我的模板中引用属性 (avg_rating) 的结果,以便显示每个用户的评分。我试过了,它显示空白结果:

{% for user in users %}
{{ user.profile.avg_rating }}

另外,这是被调用的视图:

def index(request):
    user_list = User.objects.select_related().order_by('-userrating')[:5]

    city_list = City.objects.order_by('-name')[:5]

    context_dict = {"users": user_list, "cities" : city_list}

    return render(request, "index.html", context_dict)

我目前正在通过 Django 学习,如果这很明显很抱歉。

【问题讨论】:

  • 正如塞尔丘克在他的回答中所说,问题出在avg_rating 属性上。请注意,模板可以隐藏这样的错误。如果您要添加新方法或属性,最好尝试在 shell 或视图中打印结果,然后您将看到错误消息而不是静默失败。

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


【解决方案1】:

您的avg_ratingUser 参数根本没有使用。尝试将其重写为:

def avg_rating(self):
    return self.user.userrating_set.all().aggregate(Avg('rating'))['rating__avg']

您还可以删除 @property 装饰器,因为您也可以使用相同语法(即不带 ())在 Django 模板中使用方法,例如:

{{ user.profile.avg_rating }}

【讨论】:

  • 抱歉,我现在收到此错误:'UserProfile' 对象没有属性'userrating_set'。我有 Django 的内置用户模型,与 UserProfile 一对一关系,与 UserRating 一对多关系
【解决方案2】:

UserRating 与 User 相关,而不是 UserProfile。您需要针对该模型进行查询。

但请注意,您这样做的方式非常昂贵,因为它需要为每个用户进行额外的查询+聚合。相反,您应该通过适用于查询集中所有元素的annotation 方法在视图中进行查询。

def index(request):
    user_list = User.objects.select_related().annotate(
        rating=Avg('userrating__rating')
    ).order_by('-rating')[:5]

现在您可以通过模板中的{{ user.rating }} 参考每个用户的评分。

【讨论】:

  • 我在测试页面后收到此错误。未定义全局名称“userrating__rating”。我不确定为什么它不能识别用户评分。
  • 对不起,应该用引号引起来。立即尝试。
  • 感谢您的帮助。它现在显示评级,但它们不是按平均排序(显示:​​50、100、0、35),如果我给用户两个评级,它会出现两次,而不是计算平均值并将其放在正确的位置。
  • 要按平均评分排序,请按注释字段 '-rating' 而不是 '-userrating' 排序。这也应该防止重复条目。
【解决方案3】:

1) 像 def avg_rating 这样的东西喜欢被设置为 Manager 方法。最好为 UserProfile 创建 Manager 类(例如 UserProfileManager)来处理 UserProfile 模型的所有查询。 avg_rating 定义更喜欢存在于这个 UserProfileManager 中。

2) avg_rating 定义与 UserProfile 相关,因此它应该作为 UserProfile 方法而不是 User 方法调用。

3) 在 UserProfile 类中设置 avg_rating 可能会造成混淆,而 UserRating 类是为评级内容而创建的。

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 2023-03-25
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多