Django:如何从模板中识别调用视图?

bry*_*yan 36 django

精简版:

是否有一种简单的内置方法来识别Django模板中的调用视图,而不传递额外的上下文变量?

长(原版)版:

我的一个Django应用程序有几个不同的视图,每个视图都有自己的命名URL模式,它们都呈现相同的模板.有一小部分模板代码需要根据被调用的视图进行更改,太小而不值得为每个视图设置单独模板的开销,所以理想情况下我需要找到一种方法来识别模板中的调用视图.

我试着设置的意见,额外的上下文变量传递(如"VIEW_NAME")来识别主叫观点,我已经使用也尝试过{% ifequal request.path "/some/path/" %}比较,但这些方法都显得特别优雅.有没有更好的方法从模板中识别调用视图?有没有办法访问视图的名称或URL模式的名称?


更新1:关于评论这只是我误解MVC的一个例子,我理解MVC,但Django并不是一个真正的MVC框架.我相信我的应用程序设置的方法是用Django的采取对MVC一致:意见描述提出的数据,以及模板描述如何将数据呈现.我碰巧有许多视图准备不同的数据,但都使用相同的模板,因为所有视图的数据呈现方式相同.我只是想找一种简单的方法来识别模板中的调用视图(如果存在的话).

更新2:感谢所有答案.我认为这个问题正在被推翻 - 正如我在原来的问题中所提到的,我已经考虑并尝试了所有建议的解决方案 - 所以我现在把它提炼成一个"短版本",现在问题的顶部.而现在似乎如果有人只是发布"否",它将是最正确的答案:)

更新3: Carl Meyer发布了"否":)再次感谢大家.

Tis*_*sho 24

从Django 1.5开始,url_name可以使用以下方法访问:

request.resolver_match.url_name
Run Code Online (Sandbox Code Playgroud)

在此之前,您可以使用中间件:

from django.core.urlresolvers import resolve

class ViewNameMiddleware(object):  
    def process_view(self, request, view_func, view_args, view_kwargs):
        url_name = resolve(request.path).url_name
        request.url_name = url_name
Run Code Online (Sandbox Code Playgroud)

然后在MIDDLEWARE_CLASSES中添加它,在模板中我有这个:

{% if request.url_name == "url_name" %} ... {% endif %}
Run Code Online (Sandbox Code Playgroud)

考虑到RequestContext(request)总是传递给render函数.我更喜欢使用url_name作为url,但是可以使用resolve().app_name和resolve().func.name,但这不适用于装饰器 - 而是返回装饰器函数名称.

  • 谢谢你的说明.实际上,`request.resolver_match`是在2013年的Django 1.5中引入的,而帖子是从2012年开始的.在StackOverflow中应该有一个'Obsolete'的标志:) (5认同)
  • 要在模板中使用`request.resolver_match.url_name`,必须将`django.core.context_processors.request`添加到设置`TEMPLATE_CONTEXT_PROCESSORS`中. (2认同)

Car*_*yer 18

不,这将是一个坏主意.要从模板直接引用视图函数名称,会在视图层和模板层之间引入过度紧密的耦合.

这里有一个更好的解决方案是Django的模板继承系统.定义一个公共父模板,其中包含需要在每个视图版本中更改的(小)区域的块.然后定义每个视图的模板以从父级扩展并适当地定义该块.


Has*_*tax 7

如果你的 urls.py 和views.py 中的命名是一致的(它应该是一致的),那么这将返回视图名称:

{{ request.resolver_match.url_name }}
Run Code Online (Sandbox Code Playgroud)

当您在模板中调用它时,请务必对其应用一些上下文。例如,我在这里使用它从详细视图中删除删除按钮,但在我的更新视图中删除按钮仍然会出现!

{% if request.resolver_match.url_name != 'employee_detail' %}
Run Code Online (Sandbox Code Playgroud)