1

我有很多基于类的视图,它们使用 reverse(name, args) 来查找 url 并将其传递给模板。但是,问题是必须先实例化基于类的视图,然后才能定义 urlpatterns。这意味着在 urlpatterns 为空时实例化该类,从而导致反向抛出错误。我一直在通过将 lambda: reverse(name, args) 传递给我的模板来解决这个问题,但肯定有更好的解决方案。

作为一个简单的示例,以下失败并出现异常: ImproperlyConfigured at xxxx The included urlconf mysite.urls does not have any patterns in it

mysite.urls

from mysite.views import MyClassView

urlpatterns = patterns('',
    url(r'^$' MyClassView.as_view(), name='home')
)

视图.py

class MyClassView(View):
    def get(self, request):
        home_url = reverse('home')
        return render(request, 'home.html', {'home_url':home_url})

主页.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 的视图...

编辑:

我这样使用它:

视图.py

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):

基本上我想对几种不同的内容类型使用相同的侧边栏模板。尽管侧边栏中显示的模型是任意的,但格式始终相同。

4

2 回答 2

2

home可以使用声明直接在模板中访问您的url {% url 'home' %}。这是在 urls.py 文件中访问命名 url 的标准方法。

您不必home_url在基于类的视图函数中显式地将变量发送到模板。

换句话说,在您的home.html文件中:-

<p><a href="{% url 'home' %}">Home</a></p>

会做。

于 2012-11-29T23:02:21.500 回答
2

对于您的示例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是必需的而不是反向的,因为 url conf 还没有加载。

于 2012-11-29T23:02:36.820 回答