2013-10-27 61 views
0

我的問題是,我需要知道用戶是否對某個模型實例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) 
    #.... 

在模板中我將有一個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> 

我在這裏尋找2件事情 - 使用模型方法來獲得用戶評分是否正確?到目前爲止,我遇到的問題是我無法找到如何訪問當前用戶在models.py中使用。我想到的另一個想法是以某種方式從視圖中傳遞request.current_user,但用戶不與BlogSite關聯,因此我無法對其進行過濾。

回答

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 %} 

最後,我可以去睡覺了!

0

您可以通過模板參數傳遞blog_site.rated(request.user)的結果。如果你有多個博客網站實例養活你的模板(視圖樣品中blog_sites),並在它們之間迭代的模板,你可以組的實例和rated結果到元組或類型的字典在您看來,像這樣:

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

假設result是模板中的迭代變量(因爲您將視圖命名爲search)(在模板代碼段中替換blogsite),則分別在result.siteresult.rated的模板中訪問這些模板。

因此,我個人會保留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 %} 
+0

爲了完整起見,我添加了基於您的問題和答案源代碼的代碼示例,以說明我建議的操作。但是,您的方法(在您自己的答案中)可能更有效,因爲它只涉及一個數據庫查詢來獲取評級博客站點,而不是每個博客站點通過額定方法查詢一次。 – JayK