urls.py not passing url pattern - django

I've just created a url pattern entry to route things to my registration view but the parameter is not being passed at all even though it's clearly in the URL.
My URL pattern:
url(r'^register/(?P<profile_type>\w+/?$)', 'userProfile.views.register'),
My view definition:
def register(request, profile_type=None):
The URL I try to load (not the real one, but an example):
http://example.com/register/user
When I set a pdb breakpoint right at the beginning of the view, profile_type is None, but the url is http://example.com/register/user
I tried running re.match to see if the regex was wrong, and I got the following:
match = re.match(r'^register/(?P<profile_type>\w+/?$)', 'register/user')
match
<_sre.SRE_Match object at 0x1004d48a0>
match.groupdict()
{'profile_type': 'user'}
Clearly the regex is matching the 'user' part of the URL but it's not getting passed. I would love some help with this.
The urls.py contains other patterns that are similar, and these patterns are working properly:
url(r'^user/(?P<profile_id>\d+/?$)', 'userProfile.views.registeredUser'),
The view is in the right place and is being called correctly but the parameter is not being passed.
Actually, I have a prior pattern in the file that looks like this:
url(r'^register', 'userProfile.views.register'),
I think that's getting called before the second pattern and messing things up...

Try setting APPEND_SLASH to False in settings. See that for more details

As I just added to the question part, I had a prior pattern in my file that was messing things up:
url(r'^register', 'userProfile.views.register'),
I changed it to:
url(r'^register+/?$', 'userProfile.views.register'),
And now everything works fine. /facepalm

Related

No reverse match during post [duplicate]

I have some code and when it executes, it throws a NoReverseMatch, saying:
NoReverseMatch at /my_url/ Reverse for 'my_url_name' with arguments '()' and keyword arguments '{}' not found. n pattern(s) tried: []
What does this mean, and what can I do about it?
The NoReverseMatch error is saying that Django cannot find a matching url pattern for the url you've provided in any of your installed app's urls.
The NoReverseMatch exception is raised by django.core.urlresolvers when a matching URL in your URLconf cannot be identified based on the parameters supplied.
To start debugging it, you need to start by disecting the error message given to you.
NoReverseMatch at /my_url/
This is the url that is currently being rendered, it is this url that your application is currently trying to access but it contains a url that cannot be matched
Reverse for 'my_url_name'
This is the name of the url that it cannot find
with arguments '()' and
These are the non-keyword arguments its providing to the url
keyword arguments '{}' not found.
These are the keyword arguments its providing to the url
n pattern(s) tried: []
These are the patterns that it was able to find in your urls.py files that it tried to match against
Start by locating the code in your source relevant to the url that is currently being rendered - the url, the view, and any templates involved. In most cases, this will be the part of the code you're currently developing.
Once you've done this, read through the code in the order that django would be following until you reach the line of code that is trying to construct a url for your my_url_name. Again, this is probably in a place you've recently changed.
Now that you've discovered where the error is occuring, use the other parts of the error message to work out the issue.
The url name
Are there any typos?
Have you provided the url you're trying to access the given name?
If you have set app_name in the app's urls.py (e.g. app_name = 'my_app') or if you included the app with a namespace (e.g. include('myapp.urls', namespace='myapp'), then you need to include the namespace when reversing, e.g. {% url 'myapp:my_url_name' %} or reverse('myapp:my_url_name').
Arguments and Keyword Arguments
The arguments and keyword arguments are used to match against any capture groups that are present within the given url which can be identified by the surrounding () brackets in the url pattern.
Assuming the url you're matching requires additional arguments, take a look in the error message and first take a look if the value for the given arguments look to be correct.
If they aren't correct:
The value is missing or an empty string
This generally means that the value you're passing in doesn't contain the value you expect it to be. Take a look where you assign the value for it, set breakpoints, and you'll need to figure out why this value doesn't get passed through correctly.
The keyword argument has a typo
Correct this either in the url pattern, or in the url you're constructing.
If they are correct:
Debug the regex
You can use a website such as regexr to quickly test whether your pattern matches the url you think you're creating, Copy the url pattern into the regex field at the top, and then use the text area to include any urls that you think it should match against.
Common Mistakes:
Matching against the . wild card character or any other regex characters
Remember to escape the specific characters with a \ prefix
Only matching against lower/upper case characters
Try using either a-Z or \w instead of a-z or A-Z
Check that pattern you're matching is included within the patterns tried
If it isn't here then its possible that you have forgotten to include your app within the INSTALLED_APPS setting (or the ordering of the apps within INSTALLED_APPS may need looking at)
Django Version
In Django 1.10, the ability to reverse a url by its python path was removed. The named path should be used instead.
If you're still unable to track down the problem, then feel free to ask a new question that includes what you've tried, what you've researched (You can link to this question), and then include the relevant code to the issue - the url that you're matching, any relevant url patterns, the part of the error message that shows what django tried to match, and possibly the INSTALLED_APPS setting if applicable.
A very common error is when you get with arguments ('',). This is caused by something like this:
{% url 'view-name' does_not_exist %}
As does_not_exist doesn't exist, django evaluates it to the empty string, causing this error message.
If you install django-fastdev you will instead get a nice crash saying does_not_exist doesn't exist which is the real problem.
With django-extensions you can make sure your route in the list of routes:
./manage.py show_urls | grep path_or_name
If the route is missing you probably have not imported the application.
It may be that it's not loading the template you expect. I added a new class that inherited from UpdateView - I thought it would automatically pick the template from what I named my class, but it actually loaded it based on the model property on the class, which resulted in another (wrong) template being loaded. Once I explicitly set template_name for the new class, it worked fine.
The arguments part is typically an object from your models. Remember to add it to your context in the view. Otherwise a reference to the object in the template will be empty and therefore not match a url with an object_id.
Watch out for different arguments passing between reverse() and redirect() for example:
url(r"^some_app/(?P<some_id>\d+)/$", some_view_function, name="some_view")
will work with:
reverse("some_view", kwargs={"some_id": my_id})
and:
redirect("some_view", some_id=my_id)
but not with:
reverse("some_view", some_id=my_id)
and:
redirect("some_view", kwargs={"some_id": my_id})

What is a NoReverseMatch error, and how do I fix it?

I have some code and when it executes, it throws a NoReverseMatch, saying:
NoReverseMatch at /my_url/ Reverse for 'my_url_name' with arguments '()' and keyword arguments '{}' not found. n pattern(s) tried: []
What does this mean, and what can I do about it?
The NoReverseMatch error is saying that Django cannot find a matching url pattern for the url you've provided in any of your installed app's urls.
The NoReverseMatch exception is raised by django.core.urlresolvers when a matching URL in your URLconf cannot be identified based on the parameters supplied.
To start debugging it, you need to start by disecting the error message given to you.
NoReverseMatch at /my_url/
This is the url that is currently being rendered, it is this url that your application is currently trying to access but it contains a url that cannot be matched
Reverse for 'my_url_name'
This is the name of the url that it cannot find
with arguments '()' and
These are the non-keyword arguments its providing to the url
keyword arguments '{}' not found.
These are the keyword arguments its providing to the url
n pattern(s) tried: []
These are the patterns that it was able to find in your urls.py files that it tried to match against
Start by locating the code in your source relevant to the url that is currently being rendered - the url, the view, and any templates involved. In most cases, this will be the part of the code you're currently developing.
Once you've done this, read through the code in the order that django would be following until you reach the line of code that is trying to construct a url for your my_url_name. Again, this is probably in a place you've recently changed.
Now that you've discovered where the error is occuring, use the other parts of the error message to work out the issue.
The url name
Are there any typos?
Have you provided the url you're trying to access the given name?
If you have set app_name in the app's urls.py (e.g. app_name = 'my_app') or if you included the app with a namespace (e.g. include('myapp.urls', namespace='myapp'), then you need to include the namespace when reversing, e.g. {% url 'myapp:my_url_name' %} or reverse('myapp:my_url_name').
Arguments and Keyword Arguments
The arguments and keyword arguments are used to match against any capture groups that are present within the given url which can be identified by the surrounding () brackets in the url pattern.
Assuming the url you're matching requires additional arguments, take a look in the error message and first take a look if the value for the given arguments look to be correct.
If they aren't correct:
The value is missing or an empty string
This generally means that the value you're passing in doesn't contain the value you expect it to be. Take a look where you assign the value for it, set breakpoints, and you'll need to figure out why this value doesn't get passed through correctly.
The keyword argument has a typo
Correct this either in the url pattern, or in the url you're constructing.
If they are correct:
Debug the regex
You can use a website such as regexr to quickly test whether your pattern matches the url you think you're creating, Copy the url pattern into the regex field at the top, and then use the text area to include any urls that you think it should match against.
Common Mistakes:
Matching against the . wild card character or any other regex characters
Remember to escape the specific characters with a \ prefix
Only matching against lower/upper case characters
Try using either a-Z or \w instead of a-z or A-Z
Check that pattern you're matching is included within the patterns tried
If it isn't here then its possible that you have forgotten to include your app within the INSTALLED_APPS setting (or the ordering of the apps within INSTALLED_APPS may need looking at)
Django Version
In Django 1.10, the ability to reverse a url by its python path was removed. The named path should be used instead.
If you're still unable to track down the problem, then feel free to ask a new question that includes what you've tried, what you've researched (You can link to this question), and then include the relevant code to the issue - the url that you're matching, any relevant url patterns, the part of the error message that shows what django tried to match, and possibly the INSTALLED_APPS setting if applicable.
A very common error is when you get with arguments ('',). This is caused by something like this:
{% url 'view-name' does_not_exist %}
As does_not_exist doesn't exist, django evaluates it to the empty string, causing this error message.
If you install django-fastdev you will instead get a nice crash saying does_not_exist doesn't exist which is the real problem.
With django-extensions you can make sure your route in the list of routes:
./manage.py show_urls | grep path_or_name
If the route is missing you probably have not imported the application.
It may be that it's not loading the template you expect. I added a new class that inherited from UpdateView - I thought it would automatically pick the template from what I named my class, but it actually loaded it based on the model property on the class, which resulted in another (wrong) template being loaded. Once I explicitly set template_name for the new class, it worked fine.
The arguments part is typically an object from your models. Remember to add it to your context in the view. Otherwise a reference to the object in the template will be empty and therefore not match a url with an object_id.
Watch out for different arguments passing between reverse() and redirect() for example:
url(r"^some_app/(?P<some_id>\d+)/$", some_view_function, name="some_view")
will work with:
reverse("some_view", kwargs={"some_id": my_id})
and:
redirect("some_view", some_id=my_id)
but not with:
reverse("some_view", some_id=my_id)
and:
redirect("some_view", kwargs={"some_id": my_id})

404 on a simple template view - strange

I have a django app set up consisting of ListViews, TemplateViews etc..
So, I just added a small templateview to it like so:
#views.py
class TermsTemplateView(TemplateView):
template_name = "terms.html"
#urls.py
url(r'^terms/$', TermsTemplateView.as_view(), name='terms'),
and in terms.html, I am using for linking:
Terms & Conditions
For some strange reason, I keep getting 404 on localhost/terms as follows:
404: No <model_name> found matching the query
I am baffled why this is happening all of a sudden. I have the same set up for "about", "thanks", "contact" pages, and they seem to display it with no problems.
..and the worst part is, if I modify the urls.py like so:
url(r'^/terms/$', TermsTemplateView.as_view(), name='terms'),
and then go to http://127.0.0.1:8000//terms/ - the page seems to be there.. I am surprised why this is so :(
Any help would enlighten me!
The / at the end is the culprit of your problems. localhost/terms doesn't match '^terms/$' regular expression, localhost/terms/ does.
You can make / at the end optional by using ?:
url(r'^terms/?$', TermsTemplateView.as_view(), name='terms'),
UPD: Note that there is a better solution to the problem, APPEND_SLASH:
When set to True, if the request URL does not match any of the
patterns in the URLconf and it doesn’t end in a slash, an HTTP
redirect is issued to the same URL with a slash appended.
Also see:
Why would you need a slash at the end of a URL?
django - url with automatic slash adding
Append Slashes to URLs in Django

Regex Url conf Django

I am trying to get the following setup up going.
Flatpages: Where all my static sites are (like: about, contact,..)
Dynamic Pages:
Here I am trying to link from one of the Flatpages to a start site:
the regex in the url conf of this startsite I tried was:
(r'^myapp/start/(\d+)/$', 'mysite.views.def_that_should_just_show_hello_world'),
In the views I had:
def def_that_should_just_show_hello_world(request):
return HttpResponse("Hello experiment world")
If I go to
/myapp/ I get 404: No FlatPage matches the given query.
/myapp/start/ I get 404: No FlatPage matches the given query.
/myapp/start/1 I get
Exception Type: TypeError
def_that_should_just_show_hello_world takes exactly 1 argument (2 given)
I thought with this setup I would get "Hello experiment world" on EVERY page.
Where did I go wrong?
I dont understand the multiple sites approach in regexs.
What would I have to do to print hello world on all these sites?
And then, what would I have to do to display 1 image on all of these sites?
Thanks a lot for the help!
You regular expression has a matching group in it - the (\d+) bit.
This requires one or more numeric characters to appear at the end of the url for that view. If you do not include the number at the end, this regular expression will not match the url. (url matching works like any other regular expression matching).
When you do include the number, eg. /myapp/start/1 you then have another problem. Because there is a matching group, the part of the url in the brackets will be passed as another argument to your view. Views are always passed the request as their first parameter but in this case the '1' matched by the (\d+) is provided as a second argument. This is why you are hetting the TypeError in this case.
Django's documentation has a lot of information on how url dispatching works, read that through and see if that makes sense!
from your_app_name import views
from django.conf.urls import url
urlpatterns = [
url(r'^$',views.method_name,name ='index'),
path('admin/', admin.site.urls),

URL Patterns in Django - Different Combinations

I'm finding it hard to understand what exactly is passed to the patterns method in Django.
You see, I usually have my urls.py as:
urlspatterns = patterns('example.views',
(r'/$','func_to_call'),
)
Then in func_to_call I would get everything I want from the request object by using request.path. However on a second take, it's really quite horrific that I'm ignoring Django's slickness for such a longer, less clean way of parsing - the reason being I don't understand what to do!
Let's say you have 3 servers you're putting your Django application on, all of which have a domain name and some variation like server1/djangoApplicationName/queryparams, server2/application/djangoApplicationName and server3/queryparams. What will the urlpattern get passed? The whole url? Everything after the domain name?
The URLconf regex sees only the path portion of the URL, with the initial forward-slash stripped. Query parameters are not matched by the URLconf, you access those via request.GET in your view. So you might write a pattern like this:
urlpatterns = patterns('myapp.views',
url(r'^myapp/something/$', 'something_view_func')
)
The documentation has more examples and details.