Python 模型方法或自定义模板筛选器

Python 模型方法或自定义模板筛选器,python,django,django-models,django-templates,django-views,Python,Django,Django Models,Django Templates,Django Views,我的问题是,我需要知道用户是否对某个模型实例BlogSite进行了评级。在该页面上,有多个BlogSite实例,它们具有五星级评级系统。当当前用户对某个实例进行评级时,应将其设置为只读 我遇到了一个障碍,因为如果我使用一个模型函数,我需要传递两个变量——current_user和BlogSite。我无法找到如何访问models.py中的request.user,看起来我不应该这样做 我走的另一条路是创建一个自定义过滤器——但我发现我只能传入一个参数。我宁愿不使用这种方法,因为我觉得最好将逻辑保留

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

我遇到了一个障碍,因为如果我使用一个模型函数,我需要传递两个变量——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)
    #....
在模板中,如果rated返回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>

{{blogsite.create_date}

我在这里寻找两件事——使用模型方法来获得用户是否已评级似乎是正确的方法吗?到目前为止,我遇到的问题是,我找不到如何访问要在models.py中使用的当前用户。我想到的另一个想法是以某种方式从视图中传入request.current_user,但该用户与BlogSite没有关联,因此我无法对此进行筛选。

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

({"site": block_site, "rated": block_site.rated(request.user)} for block_site in block_sites)
并分别使用
result.site
result.rated
访问模板中的这些内容,假设
result
是模板中的迭代变量(因为您将视图命名为
search
)(替换模板片段中的
blogsite

因此,我个人会在发布时使用
当前用户
参数对
方法进行评级

编辑:下面是一个混合了您的代码(问答)和我的建议的示例:

#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 %}
{%用于搜索结果%}
{%with blogsite=result.site rated=result.rated%}
{{blogsite.create_date}
{{rated}}
{%endwith%}
{%empty%}
这个国家没有注册的博客网站

{%endfor%}
我最终采取了一种稍微不同的方法,这是我在试图入睡时想到的,但却无法忘记Django:)在视图中,我创建了一个博客网站列表,某个用户留下了评论

#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 %}
#模板
{blogsites%中的blogsite为%1}
{{blogsite.create_date}
{{rated}}
{%empty%}
这个国家没有注册的博客网站

{%endfor%}

终于可以睡觉了

为了完整起见,我根据您的问答源代码添加了代码示例,以说明我打算做什么。然而,您的方法(在您自己的答案中)可能更有效,因为它只涉及一个DB查询来获得分级博客站点,而不是通过分级方法对每个博客站点进行一次查询。