Django奇怪的问题,使用反向和url标记

时间:2022-05-01 05:46:34

I've found very odd thing about using reverse in Django 1.2.1.

在Django 1.2.1中,我发现使用反向操作非常奇怪。

I have:

我有:

myapp/
   views.py
   urls.py

in urls.py

在urls . py

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

in views.py

在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')

When I put reverse method anywhere outside the view method (browse - in this case) I get an exception in every further use of reverse or {% url %} tag.

当我在视图方法(本例中为browse)之外的任何地方放置反向方法时,在每次使用反向或{% url %}标签时,都会得到一个异常。

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

WTF? When I comment/delete the print line outside browse() , second print line inside browse() magically start working!

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


The most basic case is:

最基本的情况是:

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

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

1) I define a class in main-scope that is initialized when django initialize (and runs reverse) 2) When a request comes the some_view function has been triggered and it evaluates the reverse function again (and fails with exception).

1)我在主作用域中定义一个类,当django初始化(并运行反向)时初始化这个类;

I don't see anything bad at all in this approach. Why not to initialise some values in the django main-scope with results of the reverse() function ?

我看不出这种方法有什么不好的地方。为什么不使用反向()函数的结果在django主作用域中初始化一些值呢?

3 个解决方案

#1


1  

You will probably need to pass 'request' as the second parameter when calling reverse() from within the view function after it's already been called.

当在视图函数中调用reverse()时,您可能需要将'request'作为第二个参数,在它已经被调用之后。

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

This is odd behavior indeed, but this might possibly be a solution for now.

这确实是奇怪的行为,但这可能是现在的解决方案。

#2


0  

First, you should be naming your URLs in order to use reverse. That is the correct approach AFAIK.

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

Second, why are you calling reverse from within a FormField? I really don't get it.

第二,为什么要在FormField中调用reverse ?我真的不明白。

Maybe you could enlighten us by posting the full code rather than a curated set of snippets.

也许您可以通过发布完整的代码而不是一组经过规划的代码片段来启发我们。

# 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


0  

The problem is caused by import hell in python. reverse depends on other things and cannot be used while initialization.

问题是由python中的导入地狱引起的。反向依赖于其他东西,在初始化时不能使用。

The solution is to use lazy reverse. E.g. using this: http://djangosnippets.org/snippets/499/

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

#1


1  

You will probably need to pass 'request' as the second parameter when calling reverse() from within the view function after it's already been called.

当在视图函数中调用reverse()时,您可能需要将'request'作为第二个参数,在它已经被调用之后。

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

This is odd behavior indeed, but this might possibly be a solution for now.

这确实是奇怪的行为,但这可能是现在的解决方案。

#2


0  

First, you should be naming your URLs in order to use reverse. That is the correct approach AFAIK.

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

Second, why are you calling reverse from within a FormField? I really don't get it.

第二,为什么要在FormField中调用reverse ?我真的不明白。

Maybe you could enlighten us by posting the full code rather than a curated set of snippets.

也许您可以通过发布完整的代码而不是一组经过规划的代码片段来启发我们。

# 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


0  

The problem is caused by import hell in python. reverse depends on other things and cannot be used while initialization.

问题是由python中的导入地狱引起的。反向依赖于其他东西,在初始化时不能使用。

The solution is to use lazy reverse. E.g. using this: http://djangosnippets.org/snippets/499/

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