Change template name for Django's auth views - python

Ì'm using django.contrib.auth.views.login and django.contrib.auth.views.logout directly in my urls.py with
from django.contrib.auth import views as auth_views
urlpatterns = [
url(r'^login/$', auth_views.login, name='login'),
url(r'^logout/$', auth_views.logout, name='logout'),
]
These built-in auth views are using templates in directory registration/.
How can I change template name for these views? Normally, I can use ...as_view(template_name='...').

The documentation explains this fully:
The views have optional arguments you can use to alter the behavior of the view. For example, if you want to change the template name a view uses, you can provide the template_name argument. A way to do this is to provide keyword arguments in the URLconf, these will be passed on to the view. For example:
urlpatterns = [
url(
'^change-password/',
'django.contrib.auth.views.password_change',
{'template_name': 'change-password.html'}
)
]

Related

NoReverseMatch: Reverse for 'account_confirm_email' not found. [dj-rest-auth]

I am new to Django. I'm trying to implement jet authentication along with social authentication.
I'm following this tutorial https://jkaylight.medium.com/django-rest-framework-authentication-with-dj-rest-auth-4d5e606cde4d
I tried to implement the same but its not working.
I'm getting this error:
django.urls.exceptions.NoReverseMatch: Reverse for 'account_confirm_email' not found. 'account_confirm_email' is not a valid view function or pattern name.
My project level urls.py
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularSwaggerView
)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# path('account/', include('allauth.urls')),
path('admin/', admin.site.urls),
path('api/user/', include('user.urls')),
path('api/schema/', SpectacularAPIView.as_view(), name='api-schema'),
path(
'api/docs/',
SpectacularSwaggerView.as_view(url_name='api-schema'),
name='api-docs'
),
]
My App level urls.py
from django.urls import path, re_path
from dj_rest_auth.registration.views import RegisterView, VerifyEmailView, ConfirmEmailView
from dj_rest_auth.views import LoginView, LogoutView
from user import views
app_name = 'user'
urlpatterns = [
path('account-confirm-email/<str:key>/', ConfirmEmailView.as_view()),
path('register/', RegisterView.as_view()),
path('login/', LoginView.as_view()),
path('logout/', LogoutView.as_view()),
path('verify-email/',
VerifyEmailView.as_view(), name='rest_verify_email'),
path('account-confirm-email/',
VerifyEmailView.as_view(), name='account_email_verification_sent'),
re_path(r'^account-confirm-email/(?P<key>[-:\w]+)/$',
VerifyEmailView.as_view(), name='account_confirm_email'),
path('listusers/', views.ListUsers.as_view(), name='list-users'),
]
When I try to register a user. It causes this error.
I'm using dj-rest-auth package to implement authentication.
If I replace the email verification related urls from app level to project level. Then everything is working fine.
What is causing this error ?
For the registration part, you have to use allauth which has some baked-in integrations with dj-rest-auth
also, you would have to add some things in your settings.py:
INSTALLED_APPS = [
"dj_rest_auth.registration",
"allauth",
"allauth.account"
]
AUTHENTICATION_BACKENDS = [
"allauth.account.auth_backends.AuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
]
add these URLs to the urls.py:
urlpatterns = [
path("signup/", include("dj_rest_auth.registration.urls"))
path("verify-email/", VerifyEmailView.as_view(), name="rest_verify_email"),
path(
"account-confirm-email/",
VerifyEmailView.as_view(),
name="account_confirm_email_sent",
),
path(
"account-confirm-email/<key>/",
VerifyEmailView.as_view(),
name="account_confirm_email",
),
]
The request is not getting <str:key>. Please check where you are supplying. It can be from view or template.

How to route specific urls in a django app?

I would like to know if there is a way to include only specific url endpoints in my Django urls.py.
Lets say i have a app called auth with this auth/urls.py
urlpatterns = [
url(r'^password/reset/$', PasswordResetView.as_view(),
name='rest_password_reset'),
url(r'^password/reset/confirm/$', PasswordResetConfirmView.as_view(),
name='rest_password_reset_confirm'),
url(r'^login/$', LoginView.as_view(), name='rest_login'),
url(r'^logout/$', LogoutView.as_view(), name='rest_logout'),
url(r'^user/$', UserDetailsView.as_view(), name='rest_user_details'),
url(r'^password/change/$', PasswordChangeView.as_view(),
name='rest_password_change'),
]
Now I have a urls.py like that:
urlpatterns = [
path('/', include('dj_rest_auth.urls'))
]
this includes all endpoints from auth/urls.py.
Is there a way to select (in urls.py) which URL to include? Lets say I only want login and logout to be included on my urls.py.
urlpatterns = [
path('/', include('dj_rest_auth.urls.rest_login')),
path('/', include('dj_rest_auth.urls.rest_logout'))
]
Something like that, how can I make it work?
I did this long before.
# inside view.py just create your own custom view
# rest and rest_auth import
from rest_auth.views import LoginView, LogoutView
class CustomLogoutView(LogoutView):
# yes u can keep it blank.
# over-riding just to distinguish from library views.
pass
Then inside any app's urls.py import required views and and pass then into path.
this way only required url will be exposed.
from .views import CustomLoginView
urlpatterns = [
path('login/', CustomLoginView.as_view(), name='login'),
]
Also you can directly import that views (not urls) which are included in library. and then create urls (path) from them.

Django PasswordResetDoneView Not Finding View or URL Pattern

I have been building a user account functionality for a Django app. In doing so, I have come across a problem and am uncertain of whether I am doing something wrong or have encountered an unfamiliar quirk of Django/Python. Any help is appreciated.
I have the following set of (working) urls (user_accounts/urls.py):
app_name = 'user_accounts'
urlpatterns = [
path('signup', views.UserSignUpView.as_view(), name='signup'),
path('logout', auth_views.LogoutView.as_view(), name='logout'),
path('login', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),
re_path(r'^reset/$', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset'),
re_path(r'^reset/done/$', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),
re_path(r'^reset/complete/$', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]
I have been trying to test it as follows (user_accounts/tests/test_views_forms.py):
class SuccessfulPasswordResetTests(TestCase):
def setUp(self):
email = 'jon#doe.com'
User.objects.create_user(username='john', email=email, password='123abcdef')
url = reverse('user_accounts:password_reset')
print(reverse('user_accounts:password_reset_done'))
self.response = self.client.post(url, {'email': email})
def test_redirection(self):
'''
A valid form submission should redirect to password_reset_done
'''
url = reverse('password_reset_done')
self.assertRedirects(self.response, url)
The issue is that I get the following error:
File
"/home/user-name/sites/project-web/project/user_accounts/tests/test_views_forms.py",
line 128, in setUp
self.response = self.client.post(url, {'email': email})
django.urls.exceptions.NoReverseMatch: Reverse for
'password_reset_done' not found. 'password_reset_done' is not a valid
view function or pattern name.
Yet, when I navigate directly to /user/reset/done/ in the browser, it serves the proper template.
The project's urls.py file looks as follows. Please note that I am using DjangoCMS
from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('video/', include('video_uploader.urls')),
path('user/', include('user_accounts.urls')),
path('', include('cms.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
You just need to set the success_url attribute in the PasswordResetView. Out of the box it defaults to reverse_lazy('password_reset_done') but since you're using a custom app name the url can't be resolved even though the namespace is the same.
This should do the trick:
re_path(r'^reset/$', auth_views.PasswordResetView.as_view(
template_name='user_accounts/password_reset.html',
success_url=reverse_lazy('user_accounts:password_reset_done'),
email_template_name='user_accounts/password_reset_email.html',
subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset')
This is a working code. Note the addition of success_url in several paths, which end up working as a cascade. That is one gets triggered after another. I also converted from the regex format to the path format. This may have been needed to get the thing working as well.
from django.urls import path, re_path, reverse_lazy, include
from django.contrib.auth import views as auth_views
from . import views
app_name = 'user_accounts'
urlpatterns = [
path('signup/', views.UserSignUpView.as_view(), name='signup'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('login/', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),
path('password-change/', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt', success_url = reverse_lazy('user_accounts:password_reset_done')), name='password_reset'),
path('password-change/done/', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),
#re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),
path('password-change/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html', success_url = reverse_lazy('user_accounts:password_reset_complete')), name='password_reset_confirm'),
path('password-change/complete/', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]

Django V2.1 reverse is not a valid view function or pattern name

I am very new to Django and I have created two apps in my project one is login & server_status. I have used the namespace method to access my login and server_status across both apps. It is working fine when I tried to access index but when I tried to access dashboard in server_status it is not working.
Reverse for 'server_status' not found. 'server_status' is not a valid view function or pattern name
# server_status URL
from django.urls import path
from . import views
urlpatterns = [
path('', include('server_status.urls', namespace='server_status')),
path('', include('login.urls', namespace='login')),
path('admin/', admin.site.urls),
]
# login app URL
app_name = 'login'
urlpatterns = [
path('login', views.index, name='index')
]
# project URL
from django.contrib import admin
from django.urls import include, path
app_name = 'server_status'
urlpatterns = [
path('', views.index, name='index'),
path('dashboard/', views.dashboard, name='dashboard'),
path('server_status/', views.server_status, name='server_status'),
path('request_access/', views.request_access, name='request_access'),
]
In server_status/templates/server_status/index.html
Login
I know this is very simple one, but it makes me very complicated.
In the posted code, you define urlpatterns twice, so the first set of urlpatterns is overridden by the second. Since server_status is defined in the first set, it is not present in memory, since you obliterate it in the second definition. index is the only pattern that survives. I think what you meant to do in the second stanza was to add to the urlpatterns with:
urlpatterns += [...]
To declare namespace you should do something like this:
# project URL
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('server_status.urls', namespace='server_status')),
path('', include('login.urls', namespace='login')),
path('admin/', admin.site.urls),
]
then you can use
Login
or
Server status index

Can you have a view function in your URLS.py file

This is just an academic question. I don't intend this for production but can you put a view function above your url routes in your url.py file? Something like:
from django.conf.urls import patterns, include, url
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Hello World!")
urlpatterns = patterns('',
url(r'^$', 'hello_world'),
)
Yes, the view can be in your urls file, although I wouldn't recommend it as a way to organise your Django project.
However, in the url() you should use the view itself, not a string.
urlpatterns = [
url(r'^$', hello_world),
]
Providing string view arguments e.g. 'myproject.urls.hello_world' is deprecated in Django 1.8 and removed in Django 1.10.
The view argument can be any callable, you can even use a lambda function (again, I wouldn't recommend it).
urlpatterns = [
url(r'^$', lambda req: HttpResponse("Hello World"),
]

Categories

Resources