I've been using Django since Django 1, and I've always used the same URL patterns (except when we switched from url to path).
Now I'm having an issue with 404 errors. I'll give you my Project URLS, and App URLS, and you tell me what am I doing wrong:
Project:
urlpatterns = [
path('b/', include('booking.urls')),
]
Booking App:
urlpatterns = [
path('book/<int:s>/<str:d>/', views.book, name="book"),
path('fb/', views.finalize_booking, name="finalize_booking"),
]
When I try to call {% url "finalize_booking" %}, it gives me a 404 error.
You should add forward slash at the start of of your string.
urlpatterns = [
path('/book/<int:s>/<str:d>/', views.book, name="book"),
path('/fb/', views.finalize_booking, name="finalize_booking"),]
I have been trying to load my localhost:8000/streamers/1234 however there is a bug in my urls that I cannot seem to fix. Iv tried both patterns below and I keep getting the error:
Django tried these URL patterns, in this order:
^streamers/(?P[0-9]+)/$ [name='streamer']
The current path, streamers/34/, didn't match any of these.
urlpatterns = [
#path(r'^streamers/<int:id>/', views.streamer, name='streamer'),
url(r'^streamers/(?P<id>[0-9]+)/$', views.streamer, name='streamer'),
]
if "views.streamer" is a class based view, use:
path(r'^streamers/<int:id>/', views.streamer.as_view(), name='streamer'),
Notice the "as_view()" after views.streamer.
I am trying to learn Django and I am currently stuck in an issue.
I created an app Contact and run the server, I get the error.
The error page displayed by server:
The urls.py file in the app Contact
urls.py in conatct
When the pattern in urls.py is
urlpatterns =[url(r'^$', views.form, name ='form')]
it works properly, but not with other pattern shown in the picture
Your help would be greatly appreciated.
The Page not found error message tells you what went wrong: For the URL (/contact) you requested, Django was unable to find a suitable view. Because you have debugging enabled, you get some information, including a list of registered views.
First things first: You probably have url(r'^contact/', include('contact.urls')) somewhere in your top level urls.py. This makes the URLs defined in the contact/urls.py available under the prefix /contact.
With
urlpatterns = [
url(r'^form/', views.form, name='form'),
]
in contact/urls.py you are telling Django that you want urls starting with contact/form/ to be handled by views.form.
Consequently, when you access http://localhost:8000/contact/ in your browser, there is no view associated with that URL, hence the 404. Your view is reacting to to http://localhost:8000/contact/form, not http://localhost:8000/contact.
When you change the URL pattern to
urlpatterns = [
url(r'^$', views.form, name='form'),
]
you modify the URL views.form reacts to.
I'm learning Django, and so far I always had to use URL's like
projectname/appname/viewname
but what if I don't want appname to appear in the URLs for the "default" app, how can I configure my urls so that
projectname/viewname
will load the view viewname from my default app?
P.S. : Of course my primary goal is to be able to use the URL projectname/ to load the default view for the default app.
Details
Currently my ProjectName/urls.py has this:
urlpatterns = patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root', settings.STATIC_ROOT}
),
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp1/', include('myapp1.urls', namespace='myapp1', app_name='myapp1')),
url(r'^myapp2/', include('myapp2.urls', namespace='myapp2', app_name='myapp2')),
)
so when I deploy my project to Heroku, and visit myproject.heroku.com, I get the error :
Page not found (404)
Request Method: GET
Request URL: https://myproject.herokuapp.com/
Using the URLconf defined in MyProject.urls, Django tried these URL patterns, in this order:
^static/(?P<path>.*)$
^admin/
^myapp1/
^myapp2/
I know this is supposed to be, but how do I fix (or hack) this to get myproject.heroku.com to work?
If not possible, how can I redirect the homepage to myproject/myapp1/defaultview ?
Thanks in advance !
my app's urls.py looks like this :
urlpatterns = patterns('myapp1.views',
url(r'^view1/$', 'view1', name='view1'), # the default view
url(r'^view2/(?P<oid>\d+)/(?P<pid>\d+)/$', 'view2', name='view2'),
)
Edit
After trying #Wallace 's suggestion url(r'^$', include('myapp1.urls', namespace='myapp1', app_name='myapp1')), and hitting the homepage, I now get the error:
Using the URLconf defined in myproject.urls, Django tried these URL patterns, in this order:
^static/(?P<path>.*)$
^admin/
^$ ^view1/$ [name='view1']
^$ ^view2/(?P<oid>\d+)/(?P<pid>\d+)/$ [name='view2']
^myapp2/
Tried changing your project urls.py with:
url(r'', include('myapp1.urls', ...)
This will include all urls from myapp1.urls where they all append to /.
The reason why r'^$' won't work is because the regex ends with $ which means there can only be 1 x url /, and because your app1.urls only has 2 urls defined and without a / or ^$ equivalent, the url resolver will then fail.
But be aware of url clashes, if your project has a ^view1/$ url it will clash to your app1's view1 for example.
Try not including your appname in the regular expression.
url(r'', include('myapp1.urls', namespace='myapp1', app_name='myapp1')),
I have a django application with an angular front-end. When from the front-end I try to send a request for passwordReset, I get the following error:
Reverse for 'password_reset_confirm' with arguments '()' and keyword
arguments '{u'uidb64': 'MTE', u'token': u'3z4-eadc7ab3866d7d9436cb'}'
not found. 0 pattern(s) tried: []
Its a POST request going to http://127.0.0.1:8080/rest-auth/password/reset/
Following is what my urls.py looks like:
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
url(r'^account/', include('allauth.urls'))
)
I also was having this problem, and found this github issue it said we need to add
url(r'^', include('django.contrib.auth.urls')),
on the urlpatterns.
As stated there it says that The PasswordReset view depends on django.contrib.auth.views.password_reset_confirm view.
As Roar Skullestad pointed out, the problem is with the default email template, which tries to resolve URL by reversing viewname "password_reset_confirm", which is undefined.
It is enough to register a viewname "password_reset_confirm" with a custom route and then default email template rendering will work fine.
You can register viewname with custom route by adding a path to urls.py:
urlpatterns = [
...,
path('password-reset/<uidb64>/<token>/', empty_view, name='password_reset_confirm'),
]
password-reset - custom route that password reset confirmation view. If you have SPA (Angular) - it will be the URL of your SPA view (such as the route to Angular component) that will handle the password reset.
This is the URL that will be resolved and embedded in the email. For this example it will be something like:
http://my-spa.com/app-name/password-reset/Nw/51v-490d4b372ec930e49049/
empty_view - in case of SPA (Angular), you don't really need server-side implementation, because the front end will actually handle this route. I used this implementation of a view, but it can be anything else:
from django.http import HttpResponse
def empty_view(request):
return HttpResponse('')
And since I'm using Angular, this is the route for my Angular component:
{
path: 'password-reset/:uid/:token',
component: PasswordRecoveryComponent
}
For me the problem was this line in site-packages/django/contrib/admin/templates/registration/password_reset_email.html:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
From what I understand the problem is caused by reverse lookup not working for this line in contrib/auth/urls.py:
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
name='password_reset_confirm'),
My (at least temporarily) solution was to override the template and hardcode the reverse lookup part of the url for the link in the email.
The path to the new template is specified in settings.py:
TEMPLATE_DIRS =(
"/absolute/path/to/my/templates/directory",
)
Since I am using angular front end, I also changed the link so that it triggers password reset confirmation via the angular client:
{{ protocol }}://{{ domain }}/#/passwordResetConfirm/{{ uid }}/{{ token }}
#AbimaelCarrasquillo's solutions works but you probably do not want to expose those endpoints as #dpstart mentioned in the comments.
I solved this by overriding the PasswordResetSerializer of rest-auth and simply replacing the reset form:
password_reset_form_class = PasswordResetForm
from the internal django.contrib.auth.forms.PasswordResetForm to allauth.account.forms.ResetPasswordForm
Make sure to add the following to your settings:
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':'path.to.PasswordResetSerializer'
}
For those who are still struggling with this issue, I found that the reverse look up internal view looks for reverse lookup within the core project urls and not within any application. It could work within application with some tweak, but I am not sure. But it works creating the reset urls directly on core project urls.py
{
path(r'password_reset/', PasswordResetView.as_view(template_name='password_reset_form.html'), name='password_reset'),
path(r'password_reset_done/', PasswordResetDoneView.as_view(template_name='password_reset_done.html'), name='password_reset_done'),
path(r'password_reset_confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(template_name='password_reset_confirm.html'), name='password_reset_confirm'),
path(r'password_reset_complete/', PasswordResetCompleteView.as_view(template_name='password_reset_complete.html'), name='password_reset_complete'),
}
Well I was also facing this problem. Every time I entered my email and pressed the button it took me to NoReverseMatch url, and I am using:
re_path(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),name='password_reset_confirm')
(url is not used to match regex in django anymore re_path is used)
My solution is to change the regex a little bit because the "csrf token" is longer than 20 words – that's why I was getting an error and you should try the same.
re_path(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,40})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),
name='password_reset_confirm')
You can either use + (in regex it means one or more) or {1,40} (in regex it means match from 1 to 40)
Add this to your project url.py file
url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
url('', include('social.apps.django_app.urls', namespace='social')),
Check out the FAQ: It explains this error and how to fix it. It references you to the demo program which contains:
# this url is used to generate email content
url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),
name='password_reset_confirm'),
My solution was to override the email template that calls the reverse of "password_reset_confirm". Make sure email template sends a URL to your frontend app with the UID and Token in the URL (instead of trying to reverse "password_reset_confirm").
Your frontend's route should take the URL, parse it and then with the updated user's password and send it back as an API call to your backend to confirm.
I resolved this issue by moving these:
path('reset_password/', auth_views.PasswordResetView.as_view(), name='password_reset'),
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset_password_sent/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset_password_complete/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
from accounts/urls.py to yourProjectName/urls.py.
I guess that path('', include("accounts.urls")), was causing the problem.
I have a headless backend, so adding or renaming URLs only for this was not a good option.
The issue is on the email template, you can override it. Just take care that you have the correct path on the settings.
In my case I have all this logic inside users app. So I have something like this.
users/templates/registration/password_reset_email.html
Inside this template I have a new custom message without the reverse URL call.
If you need more than just override the template, or maybe you need to send additional data to the template. You must override the serializer also. To do that you have to create your new serializer
from dj_rest_auth.serializers import PasswordResetSerializer as RestPasswordResetSerializer
class PasswordResetSerializer(RestPasswordResetSerializer):
def get_email_options(self):
return {
'html_email_template_name': 'registration/password_reset_email_html.html', # if you want to use an HTML template you can declare here
'extra_email_context': {'custom_key': 'custom value for my template',}
}
and add to settings.
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':'path.to.PasswordResetSerializer'
}
On the serializer you can add custom validation if needed also.
In your views.py, if you have set a token, pass it along with the path similar to:
path('resetpassword_validate/<uidb64>/<token>/', views.resetpassword_validate, name='resetpassword_validate'),