2016-08-17 46 views
1

鑑於以下型號:如何訪問模板中的自定義反向模型管理器?

class Author(models.Model): 
    name = models.CharField(max_length=20) 

class CustomQuerySet1(models.QuerySet): 
    def some_method(self): 
     return 'custom queryset 1' 

class CustomQuerySet2(models.QuerySet): 
    def some_method(self): 
     return 'custom queryset 2' 

class Book(models.Model): 
    author = models.ForeignKey(Author, related_name='books') 
    title = models.CharField(max_length=50) 

    objects = models.Manager() 
    custom1 = CustomQuerySet1.as_manager() 
    custom2 = CustomQuerySet2.as_manager() 

在我REPL我可以訪問自定義,像這樣的相關管理人員:

>>> author = Author.objects.create(name='John') 
>>> book = Book.objects.create(author=author, title='Hello') 
>>> author.books(manager='custom1').some_method() 
    'custom queryset 1' 
>>> author.books(manager='custom2').some_method() 
    'custom queryset 2' 

而且在我們的模板,我們通常是通過默認的管理員訪問相關的對象,像這樣:

{% for book in author.books.all %} 
    {{ book.title }} 
{% endfor %} 

我們顯然不允許進行函數調用並傳遞模板中的參數:

{% for book in author.books(manager='custom1').some_method %} 
{% endfor %} 

那麼是否有一種本地方式來訪問我不知道的模板中的這些自定義相關模型管理器?有沒有這樣的想法?任何外箱解決方案?

編輯: 如果有意見中的一些困惑,我是不是提示如下:

def some_view(request): 
    context = {} 
    template = 'my_template.html' 
    context['author'] = Author 
    return render(request, template, context) 

,然後調用author.objects.all而是:

def some_view(request): 
    context = {} 
    template = 'my_template.html' 
    author = Author.objects.get(name='John') 
    context['author'] = author 
    return render(request, template, context) 

,然後訪問author.books.custom1.some_method 。請注意0​​模型上定義的author上的related_name

+1

我不認爲這是可能的atm。你可以做的是在視圖中創建查詢集並將其傳遞給模板。它實際上是首選的方式,因爲概念上模板不應觸發查詢。 – spectras

+1

從我所看到的我不認爲這是可能的。鑑於查詢集是懶惰的,模板不會始終觸發查詢?不會阻止模板中的查詢屬於'select_related'和'prefetch_related'之類的東西嗎? –

+0

關鍵是視圖負責創建它,而不是模板。確實,他們很懶,所以模板評估會觸發它們,但這是一個實現細節。例如,模板可能在'all_books'上循環,但是視圖需要定義什麼是'all_books'。 – spectras

回答

0

沒有,我認爲它不會(因爲它不應該)。 模板是數據最終呈現的地方,所以它應該全部準備好,模板標記僅用於以便捷的方式呈現它。

但是,它對於模板過濾器來說可能是個不錯的主意。

+1

你能詳細說明爲什麼它不應該?在模板中調用'author.books.all'和'author.books(manager ='custom1')。custom_method'之間有什麼區別?另外,我們可以在默認模型管理器上編寫自定義方法,並在模板'author.books.i_only_want_a_subset_of_this_authors_books'中訪問它們。 –

+0

您不應該在模板中調用'author.books.all'。它的工作原理並不意味着它是正確的。看看Django的通用視圖是如何工作的,它們設計得非常好。在任何時候,他們都不會給模板或模板經理。 – spectras

+0

我從來沒有聽過這個建議。即使是[Django教程](https://docs.djangoproject.com/en/1.10/intro/tutorial03/#use-the-template-system)也會提示。 –

相關問題