模型方法或自定义模板过滤器

时间:2013-10-27 18:01:16

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

我的问题是我需要知道用户是否对某个模型实例,BlogSite进行了评级。在页面上,有多个BlogSite实例,它们具有5星评级系统。当前用户对某个实例进行评级时,应将其设置为只读。

我遇到了障碍,因为如果我使用模型函数,我需要传递2个变量 - current_user和BlogSite。我一直无法找到如何访问models.py中的request.user,看起来我不应该这样做?

我失败的另一条路径是创建一个自定义过滤器 - 但我发现我只能传入一个参数。我宁愿不做这种方法因为我觉得将逻辑保留在views.py

中会更好

有没有人知道如何解决这个问题?

#models.py
class BlogSite(models.Model):
    #fields

#get the average rating for a blogsite
def rating_avg(self):
    rating_dict = BlogSiteReview.objects.filter(blog_site=self).aggregate(Avg('review_rating'))
    rating_avg = rating_dict.get('review_rating__avg')
    if rating_avg:
        return rating_avg
    else:
        #no ratings
        return 0

def rated(self, current_user):
    #If there is a row for the blogsitereview with this blogsite for the logged in user, return True, else False
    #can I access the current user? This does not work, seems like I can't get request here.
    current_user = request.user
    review = BlogSiteReview.objects.filter(blog_site=self, user=current_user)

    if review:
        return True
    else:
        return False

class BlogSiteReview(models.Model):
    blog_site = models.ForeignKey(BlogSite)
    user = models.ForeignKey(User)
    #other fields

以下是该观点的相关部分:

#views.py
def search(request, type, regionValue):
    #....
    #ideally, the solution would be to have a field or function in the BlogSite model
    blog_sites = BlogSite.objects.filter(country=region.id, active=True)
    #....

在模板中,如果rating返回True,我会有一个if语句来添加一个类

<tr>
    <td><a href="http://{{ blogsite.url }}" id="{{ blogsite.id }}">{{ blogsite.site_name }}</a></td>
    <td><div id="rating{{ blogsite.id }}" class="rating {% if blogsite.user_rated %}jDisabled{% endif %}" data-average="{{ blogsite.rating_avg }}" data-id="{{ blogsite.id }}"></div></td>
    <td>{{ blogsite.create_date }}</td>
</tr>

我在这里寻找两件事 - 使用模型方法来获取用户评价的方法是否正确?到目前为止我遇到的问题是我无法找到如何访问要在models.py中使用的当前用户。我想到的另一个想法是以某种方式从视图中传递request.current_user,但是用户没有与BlogSite相关联,所以我无法对其进行过滤。

2 个答案:

答案 0 :(得分:0)

您可以通过模板参数传递blog_site.rated(request.user)的结果。如果您为模板提供多个BlogSite实例(视图示例中为blog_sites)并在模板中对其进行迭代,则可以将实例和rated结果分组到视图中的元组或词组中,如此:

({"site": block_site, "rated": block_site.rated(request.user)} for block_site in block_sites)

分别使用result.siteresult.rated在模板中访问这些内容,假设result是模板中的迭代变量(因为您将视图命名为search) (替换模板代码段中的blogsite)。

因此,我个人会保留rated方法,并使用current_user参数发布。

编辑:这是一个混合你的代码(问题和答案)和我的提议的例子:

#views.py
def search(request, type, regionValue):
    #....
    blog_sites = BlogSite.objects.filter(country=region.id, active=True)
    search_results = ({"site": block_site, "rated": block_site.rated(request.user)} for block_site in block_sites)
    return render(request, page, {..., 'search_results': search_results})

在模板中:

{% for result in search_results %}
  {% with blogsite=result.site rated=result.rated %}
    <tr>
      <td><a href="http://{{ blogsite.url }}" id="{{ blogsite.id }}">{{ result.site.site_name }}</a></td>
      <td><div id="rating{{ blogsite.id }}" class="rating {% if rated %}jDisabled{% endif %}" data-average="{{ blogsite.rating_avg }}" data-id="{{ blogsite.id }}"></div></td>
      <td>{{ blogsite.create_date }}</td>
      <td>{{ rated }}</td>
    </tr>
  {% endwith %}
{% empty %}
  <p>There are no registered blogsites for this country.</p>
{% endfor %}

答案 1 :(得分:0)

我最终采取了一种略微不同的方法,当我试图入睡时我想到但却无法让Django失控:)在视图中我创建了一个blog_sites列表,某个用户留下了评论

#views.py
rated = BlogSiteReview.objects.filter(user=request.user).values_list('blog_site', flat=True)
return render(request, page, {..., 'blogsites':blog_sites, 'rated':rated})

在模板中,如果blog_site FK id在blog_sites for循环中,我添加了一个类:

#template
{% for blogsite in blogsites %}
<tr>
  <td><a href="http://{{ blogsite.url }}" id="{{ blogsite.id }}">{{ blogsite.site_name }}</a></td>
  <td><div id="rating{{ blogsite.id }}" class="rating {% if blogsite.id in rated %}jDisabled{% endif %}" data-average="{{ blogsite.rating_avg }}" data-id="{{ blogsite.id }}"></div></td>
  <td>{{ blogsite.create_date }}</td>
  <td>{{ rated }}</td>
</tr>
{% empty %}
  <p>There are no registered blogsites for this country.</p>
{% endfor %}

最后我现在可以去睡觉了!