2009-08-16 100 views
2

我有一個模型書可以添加到用戶的收藏夾。所以我定義的2類:Django模板用戶請求


class Book(models.Model): 
    name = models.CharField(max_length = 40) 

class UserFavorite(models.Model): 
    book = models.ForeignKey(Book) 
    user = models.ForeignKey(User) 

現在我想顯示在主菜單頁的暢銷書帶圖標或者「添加到收藏夾」或「從收藏夾中刪除」。基本上,我將流行的書籍數組傳遞給一個模板,並從模板中循環這個數組,並應該說「如果book.is_in_favorites(request.user):...」,但這不可能從模板中獲得。

回答

3

對此的最常見方法是裝飾視圖中的書籍對象。在視圖代碼,遍歷所有的書籍,增加布爾值,指示他們是否是當前用戶的喜愛與否:

for b in books: 
    b.is_fav = b.is_in_favorites(request.user) 

然後在模板:

{% for b in books %} 
    blah blah {{b.blah}} 
    {% if b.is_fav %}FAVORITE INDICATOR{% endif %} 
{% endfor %} 

如果你不這樣做像修改書的對象,你可以與他們的註釋包紮書籍類型的字典列表:

book_info = [{'book':b, 'is_fav':b.is_in_favorites(request.user)} for b in books] 

,並在你的模板中使用它:

{% for bi in book_info %} 
    blah blah {{b.book.blah}} 
    {% if bi.is_fav %}FAVORITE INDICATOR{% endif %} 
{% endfor %} 
+0

1)我必須在Book模型中定義is_fav嗎?或者這會添加一個「即時」字段? 2)方法很好,雖然它需要運行許多選擇語句(一個用於所有書籍,然後每個書籍用於is_fav),這會影響性能。可能有什麼辦法做到這一點,只有一個查詢獲取所有的書籍? – Vitaly 2009-08-16 18:45:40

+0

事實上,我發現有「額外」的條款,可以動態地添加屬性,我會盡量利用它 – Vitaly 2009-08-16 18:55:55

+0

如果你想避免for語句引起的重複查找(並且因爲select_related *不會*在這裏幫助)您可以調用UserFavorites.objects.filter(user = request.user),並將您的書籍迭代與返回的UserFavorites集合進行比較。然後它只有2個數據庫點擊。 – 2009-08-16 18:57:20

1

我不明白這與模板有什麼關係。你只需要顯示一個鏈接到一個視圖,該視圖將book id作爲參數,從請求中獲取用戶,並使用這兩個用戶添加UserFavourite。

編輯後更新:好的,我現在明白你的問題了。那麼,正如你發現的那樣,這種事情太複雜了,無法放入模板邏輯。它確實需要在您的視圖或模板標籤中進行。可能模板標籤是最好的,因爲您無疑會希望在多個視圖/模板中使用此功能。

您可能會想要使用包含標籤,因爲它具有可以自動獲取上下文的好處。喜歡的東西(未經測試):

@register.inclusion_tag('add_to_favourites.html', takes_context=True) 
def favourite_links(context): 
    user = context['request'].user 
    books = Book.objects.exclude(userfavourite__in=user) 
    return {'books': books, 'user':user} 

現在你只需要這使得使用通過上述標籤返回書籍值的列表中選擇模板片段。在您的主要模板中,只需使用favourite_links即可顯示書籍鏈接。

+0

基本上,我將一系列流行書籍從主視圖傳遞到模板。現在從模板我循環這個數組,並應該說像「如果book.is_in_favorites(request.user)」 - 這是不可能的這樣的smthth。我現在不在乎如何實現將本書添加到收藏夾的視圖。 – Vitaly 2009-08-16 18:27:11