我有很多基于类的视图,它们使用reverse(name,args)来查找url并将其传递给模板。但是,问题是必须在定义urlpatterns之前实例化基于类的视图。这意味着在urlpatterns为空时实例化类,导致反向抛出错误。我一直在努力将lambda:reverse(name,args)传递给我的模板,但肯定有更好的解决方案。
作为一个简单的例子,下面的例外失败:在xxxx处不正确配置包含的urlconf mysite.urls中没有任何模式
mysite.urls
from mysite.views import MyClassView
urlpatterns = patterns('',
url(r'^$' MyClassView.as_view(), name='home')
)
views.朋友
class MyClassView(View):
def get(self, request):
home_url = reverse('home')
return render(request, 'home.html', {'home_url':home_url})
home.html的
<p><a href={{ home_url }}>Home</a></p>
我目前正在通过将views.py更改为强制反向运行模板渲染来解决此问题
class MyClassView(View):
def get(self, request):
home_url = lambda: reverse('home')
return render(request, 'home.html', {'home_url':home_url})
它有效,但这真的很难看,肯定有更好的方法。那么有没有办法在基于类的视图中使用反向,但避免urlpatterns的循环依赖需要视图需要反向需要urlpatterns ...
编辑:
我正在使用它:
views.朋友
def sidebar_activeusers(cls):
sidebar_dict = {'items' = []}
qs = models.random.filter.on.users
for user in qs:
item = {
'value': user.name,
'href': reverse('user_profile', args=[hash_id(user.id)])}
sidebar = loader.get_template('sidebar.html')
cls.base_dict['sidebar_html'] = sidebar.render(Context(sidebar_dict))
return cls
@sidebar_activeusers
class MyView1(View):
base_dict = {}
...
@other_sidebar_that_uses_same_sidebar_template
class MyView2(View):
基本上我想对几种不同的内容类型使用相同的侧边栏模板。虽然侧栏中显示的模型是任意的,但格式将始终相同。
对于你的例子MyClassView
,可以使用reverse
class MyClassView(View):
def get(self, request):
home_url = reverse_lazy('home')
return render(request, 'home.html', {'home_url': home_url},
定义类时不调用reverse
方法 - 仅在处理请求并调用get
方法时调用它,因此不应该出现错误。我测试了上面的例子,它工作正常。
但是,当您使用sidebar_activeusers
装饰器时,reverse
调用在加载url conf之前发生。在这种情况下,您可以使用reverse_lazy
。以下是reverse_lazy
的实例:
from django.core.urlresolvers import reverse_lazy
class MyOtherClassView(View):
home_url = reverse_lazy('home')
def get(self, request):
return render(request, 'home.html', {'home_url':self.home_url})
这次,在定义类时设置home_url
,因此需要reverse_lazy
而不是reverse,因为url conf尚未加载。
您可以使用声明home
直接在模板中访问您的{% url 'home' %}
网址。这是在urls.py文件中访问命名网址的标准方法。
您不必在基于类的视图函数中明确地将home_url
变量发送到模板。
换句话说,在你的home.html
文件中: -
<p><a href="{% url 'home' %}">Home</a></p>
会做。