问题
I was having some problems with the regex in urls.py (I am a beginner to django as well as regexes in general)
Here is my original urls.py
url(r'^name/(?P<name>\w+)/$', 'course.views.name'),
url(r'^', 'course.views.index'),
And I was trying to access it using this:
http://127.0.0.1:8000/name/blah/
My view looks like:
def index(request):
return HttpResponse("Hello, sam. You're at the course index.")
def name(request, name):
return HttpResponse("Hello, %s. You're at the course index." % name)
The result I was getting was that for no matter what input I gave, I would regularly get the "index" function, and not the "name" function. I thought the problem was with the first regex.
But then, I changed the the 2nd one to:
url(r'^$', 'course.views.index'),
And THIS works just the way I figured it to work!
I understand that "$" means end of line, but shouldnt the 1st regex have been evaluated first? What is the order in which these expressions are matched?
Adding a "$" to every url is not that big a deal, but I would like to understand why I am putting it there.
I am using Django1.4 and Python 2.7
回答1:
Read the Django document
How Django processes a request
When a user requests a page from your Django-powered site, this is the algorithm the system follows to determine which Python code to execute:
- Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has an attribute called urlconf (set by middleware request processing), its value will be used in place of the ROOT_URLCONF setting.
- Django loads that Python module and looks for the variable urlpatterns. This should be a Python list, in the format returned by the function django.conf.urls.patterns().
- Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
- Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function. The view gets passed an HttpRequest as its first argument and any values captured in the regex as remaining arguments.
- If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See Error handling below.
It said 3. Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
So I think this is a bug.
You should add $
in every url pattern unless Including other URLconfs
回答2:
You're right, the django doc tells:
How Django processes a request
When a user requests a page from your Django-powered site, this is the algorithm the system follows to determine which Python code to execute:
- Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has an attribute called urlconf (set by middleware request processing), its value will be used in place of the ROOT_URLCONF setting.
- Django loads that Python module and looks for the variable urlpatterns. This should be a Python list, in the format returned by the function django.conf.urls.patterns().
- Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
- Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function. The view gets passed an HttpRequest as its first argument and any values captured in the regex as remaining arguments.
- If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See Error handling below.
This is also what another SO post suggests to fix another URL evaluation issue.
来源:https://stackoverflow.com/questions/10878103/what-is-the-urls-py-regex-evaluation-order-in-django