2016-08-17 51 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)也会提示。 –