【问题标题】:Django odd problem with using reverse and url tagDjango使用反向和url标签的奇怪问题
【发布时间】:2010-09-09 21:42:19
【问题描述】:

我发现在 Django 1.2.1 中使用反向非常奇怪

我有:

myapp/
   views.py
   urls.py

在 urls.py 中

from django.conf.urls.defaults import *
urlpatterns = patterns('myapp.views',
 url(r'^$', 'browse'),
)

在views.py中

from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse

print reverse('myapp.views.browse')     # <----- this will print correct value  

def browse (request):
    print reverse('myapp.views.browse') # <----- this fails with exception
    return render_to_response('myapp/browse.html')

当我将 reverse 方法放在视图方法之外的任何地方(浏览 - 在这种情况下)时,我在每次进一步使用 reverse 或 {% url %} 标记时都会遇到异常。

NoReverseMatch at /
Reverse for 'myapp.views.browse' with arguments '()' 
and keyword arguments '{}' not found.

WTF?当我评论/删除 browse() 外的打印行时, browse() 内的第二个打印行神奇地开始工作!


最基本的情况是:

class MyForm(forms.Form):
   field = forms.CharField(default=reverse(....))

def some_view(request):
   print reverse(...)
   ....

1) 我在主作用域中定义了一个在 django 初始化时初始化的类(并反向运行) 2) 当请求到来时, some_view 函数已被触发,它再次评估 reverse 函数(并因异常而失败)。

我在这种方法中根本没有看到任何不好的。为什么不用 reverse() 函数的结果初始化 django 主作用域中的一些值?

【问题讨论】:

    标签: django url tags reverse


    【解决方案1】:

    从视图函数中调用 reverse() 后,您可能需要将“请求”作为第二个参数传递。

    def browse(request):
        print reverse('myapp.views.browse', args=[request])
    

    这确实是一种奇怪的行为,但这可能是目前的解决方案。

    【讨论】:

    • 为什么这会影响 url 的反转方式?如果它在视图之外工作,我认为完全相同的调用将在视图内部工作。
    • 我相信它与变量范围和导入视图的时间有关。您的反向调用被缓存在不同的范围内,因此它不能在浏览函数中工作......很可能。
    【解决方案2】:

    首先,您应该命名您的 URL 以便使用反向。这是正确的方法 AFAIK。

    其次,为什么要从 FormField 中调用 reverse?我真的不明白。

    也许您可以通过发布完整代码而不是一组精选的 sn-ps 来启发我们。

    # urls.py
    
    url(r'^/$', 'home_view', name='home'),
    url(r'^login/$', 'login_view', name='login'),
    
    
    # views.py
    from django.shortcuts import render_to_response
    from django.template import RequestContext
    from django.http import HttpResponseRedirect
    
    def login_view(request):
        # do login stuff and redirect to home
        return HttpResponseRedirect(reverse('home'))
    
    def home(request):
        # do home stuff
    
        return render_to_response("home.html", locals(), context_instance=RequestContext(request))
    

    【讨论】:

      【解决方案3】:

      问题是由python中的import hell引起的。 reverse 依赖于其他东西,不能在初始化时使用。

      解决方案是使用惰性反向。例如。使用这个: http://djangosnippets.org/snippets/499/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-04
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 2011-06-26
        • 2011-10-22
        相关资源
        最近更新 更多