Django Admin automatically logout after get data from user - django

I am facing an problems in django admin panel. My django admin panel autumatically logout When any user submitting contact-form. How to stop automatically logout? I am facing this problems after add session in my views.py. here is my code:
#views.py
from django.shortcuts import render,HttpResponseRedirect,redirect
from contact.forms import ContactForm
from contact.models import Contact
from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse
# Create your views here.
#csrf_exempt
def home_view(request,*args,**kwargs):
name = None
obj = None
if request.method == "POST":
contact_form = ContactForm(request.POST)
if contact_form.is_valid():
name = request.POST['name']
email = request.POST['email']
subject = request.POST['subject']
message = request.POST['message']
save_details = Contact(name=name,email=email,subject=subject,message=message)
save_details.save()
request.session['name'] = name
request.session.set_expiry(1) #if I remove this line then it fix the logout problems but not clearing the session after refresh.
return redirect(home_view)
#return render(request, 'index.html',{'message_name':name})
else:
print("not submitted")
else:
contact_form = ContactForm()
return render(request, 'index.html',{'form':contact_form,'message_name':obj})
#urls.py
from django.urls import path
from pages import views
urlpatterns = [
path('', views.home_view, name="home"),
]
root urls.py
from django.contrib import admin
from django.urls import path,include
from pages import urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('pages.urls')),
]
#index.html
{% if request.session.name %}
<div class="centerTest">
<h1> Thanks {{ request.session.name }} for your message. We will get back to you very soon</h1>
</div>
{% else %}
<div class="contact__container bd-grid">
<form action="#contact" method = "POST" class="contact__form">
{% for error in form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endfor %}
<label>Name:</label>
{{ form.errors.name }}
<input type="text" placeholder="Name" name="name" class="contact__input" {% if form.is_bound %}value="{{ form.name.value }} {% endif %}">
<label>Email:</label>
{{ form.errors.email }}
<input type="mail" placeholder="Email" name="email" class="contact__input" {% if form.is_bound %}value="{{ form.email.value }} {% endif %}">
<label>Subject:</label>
{{ form.errors.subject }}
<input type="text" placeholder="optional" name="subject" class="contact__input" {% if form.is_bound %}value="{{ form.subject.value }} {% endif %}">
<label>Message:</label>
{{ form.errors.message }}
<textarea name="message" placeholder="message" id="" cols="0" rows="10" class="contact__input" >{% if form.is_bound %}{{ form.message.value }} {% endif %}</textarea>
<input type="submit" value="Send" class="contact__button button">
{% endif %}
</form>
my django madmin panel autuomatically logout when any user submitting contact-form. How to stop this? anyone please help

I'd avoid using session for this purpose, but if you want to do it, then remove it from the session at the moment when you are about to display the "thank you message"
def home_view(request,*args,**kwargs):
if request.method == "POST":
...
else:
# you are about to display the "thank you message", so remove it from session here
# check if name is in session
if 'name' in request.session:
# not sure from top of my head if session allows `pop`, if not then get value first and then remove it
thanks_name = request.session.pop('name')
else:
thanks_name = None
contact_form = ContactForm()
return render(request, 'index.html',{'form':contact_form,'message_name':obj, 'thanks_name': thanks_name})
how to do it without using session? Use Django Messages which is built exactly for such use-cases. First you Add Message in view, and then you display it in template:
from django.contrib import messages
if request.method == "POST":
messages.add_message(request, messages.INFO, 'Thanks for your message. We will get back to you very soon')
template:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
also why do you use #csrf_extempt? Add {% csrf_token %} into your form instead.

Related

How to retain two forms data in the same view/template/page?

I have two forms and two views using the same profile.html template. When I GET/POST to the ProfileUpdateView, all of the users profile data is present. However, when I post to UserDeleteView and not select the "accountActivation" box the page renders but the user profile data which is above is empty.
# urls.py
from django.contrib import admin
from django.urls import include, path
from apps.iam.views import ProfileUpdateView, UserDeleteView
urlpatterns = [
path("accounts/profile", ProfileUpdateView, name="profile_detailupdate"),
path("accounts/delete", UserDeleteView, name="user_delete"),
]
# views.py
import zoneinfo
from django.contrib.auth import get_user_model
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import HttpResponseRedirect, get_object_or_404, render
from django.utils import timezone
from django.views.decorators.http import require_http_methods
from django.views.generic import TemplateView, UpdateView
from .forms import ProfileForm
from .models import Profile
User = get_user_model()
# Homepage
class HomeDetailView(TemplateView):
template_name = "home.html"
# Profile
## Update
#login_required
#require_http_methods(["GET","POST"])
def ProfileUpdateView(request):
# dictionary for initial data with field names as keys
context = {}
# fetch the object related to passed id
profile_object = get_object_or_404(Profile, id=request.user.id)
# pass the object as instance in form
profile_form = ProfileForm(request.POST or None, instance=profile_object)
# save the data from the form
if profile_form.is_valid():
profile_form.save()
# add form dictionary to context
context["profile_form"] = profile_form
# activate the new timezone in case changed
request.session["django_timezone"] = request.user.profile.timezone
timezone.activate(zoneinfo.ZoneInfo(request.user.profile.timezone))
return render(request, "profile.html", context)
## Delete
#login_required
#require_http_methods(["POST"])
def UserDeleteView(request):
# dictionary for initial data with field names as keys
context = {}
# fetch the object related to passed id
user_object = get_object_or_404(Profile, id=request.user.id)
# pass the object as instance in form
userdelete_form = ProfileForm(request.POST or None, instance=user_object)
# add form dictionary to context
context["userdelete_form"] = userdelete_form
# user verified account deletion
if request.POST.get("accountActivation") == "on":
User = get_user_model()
user_pk = request.user.pk
auth_logout(request)
User.objects.filter(pk=user_pk).delete()
return render(request, "home.html", context)
else:
return render(request, "profile.html", context)
{% extends 'base.html' %}
{% load static %}
{% load widget_tweaks %}
{% block head_title %} {{ title }} {% endblock %}
{% block body %}
<div class="container-xxl flex-grow-1 container-p-y">
<div class="row">
<div class="col-md-12">
<div class="card mb-4">
<h5 class="card-header">Profile Details</h5>
<!-- Account -->
<div class="card-body">
<div class="d-flex align-items-start align-items-sm-center gap-4">
<img src="{% static 'img/avatars/1.png' %}" alt="user-avatar" class="d-block rounded"
height="100" width="100" id="uploadedAvatar" />
<div class="button-wrapper">
<label for="upload" class="btn btn-primary me-2 mb-4" tabindex="0">
<span class="d-none d-sm-block">Upload new photo</span>
<i class="bx bx-upload d-block d-sm-none"></i>
<input type="file" id="upload" class="account-file-input" hidden
accept="image/png, image/jpeg" />
</label>
<button type="button" class="btn btn-outline-secondary account-image-reset mb-4">
<i class="bx bx-reset d-block d-sm-none"></i>
<span class="d-none d-sm-block">Reset</span>
</button>
<p class="text-muted mb-0">Allowed JPG, GIF or PNG. Max size of 800K</p>
</div>
</div>
</div>
<hr class="my-0" />
<div class="card-body">
<form id="formAccountSettings" method="POST" action="{% url 'profile_detailupdate' %}">
<!-- Security token by Django -->
{% csrf_token %}
<!-- form -->
{% for hidden in profile_form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="row">
{% for field in profile_form.visible_fields %}
<div class="mb-3 col-md-6">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if field.field.widget.input_type == "select" %}
{{ field|add_class:'form-control form-select' }}
{% else %}
{{ field|add_class:'form-control' }}
{% endif %}
{% for error in field.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
</div>
{% endfor %}
<div class="mt-2">
<button name="profile" type="submit" class="btn btn-primary me-2">Save changes</button>
<button type="reset" class="btn btn-outline-secondary">Cancel</button>
</div>
</form>
</div>
<!-- /Account -->
</div>
<div class="card">
<h5 class="card-header">Delete Account</h5>
<div class="card-body">
<div class="mb-3 col-12 mb-0">
<div class="alert alert-warning">
<h6 class="alert-heading fw-bold mb-1">Are you sure you want to delete your account?</h6>
<p class="mb-0">Once you delete your account, there is no going back. Please be certain.</p>
</div>
</div>
<form id="formAccountDeactivation" method="POST" action="{% url 'user_delete' %}">
<!-- Security token by Django -->
{% csrf_token %}
<!-- form -->
{% for hidden in deleteuser_form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" name="accountActivation"
id="accountActivation" />
<label class="form-check-label" for="accountActivation">I confirm my account
deactivation</label>
</div>
<button name="delete" type="submit" class="btn btn-danger deactivate-account">Deactivate Account</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
The issue was in the view which is shared below. I added logic to save the form if valid or read from the database if not. If anyone has suggestions to simply the below that would be great.
"""
file : views.py
reference : https://docs.djangoproject.com/en/4.1/topics/http/views/
https://docs.djangoproject.com/en/4.1/topics/class-based-views/
"""
import re
import zoneinfo
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import HttpResponseRedirect, get_object_or_404, render
from django.utils import timezone
from django.views.decorators.http import require_http_methods
from django.views.generic import TemplateView, UpdateView
from django.views.generic.base import ContextMixin, TemplateResponseMixin
from django.views.generic.edit import ProcessFormView
from .forms import DeleteUserForm, ProfileForm
from .models import Profile
User = get_user_model()
# Homepage
class HomeDetailView(TemplateView):
template_name = "home.html"
# # Profile
#login_required
#require_http_methods(["GET","POST"])
def ProfileUpdateView(request):
context = {}
profile_object = Profile.objects.get(user=request.user.id)
# display profile
if request.method == 'GET':
profile_form = ProfileForm(None, instance=profile_object)
user_form = DeleteUserForm(request.POST)
# update profile or delete account
if request.method == 'POST':
# associate request.POST to form
profile_form = ProfileForm(request.POST, instance=profile_object)
user_form = DeleteUserForm(request.POST)
# profile_form
if 'btn-profile-submit' in request.POST:
# validate form
if profile_form.is_valid():
# valid: update database
profile_form.save()
# activate the new timezone in case changed
request.session["django_timezone"] = request.user.profile.timezone
timezone.activate(zoneinfo.ZoneInfo(request.user.profile.timezone))
messages.error(request, 'Successful profile update.')
else:
# invalid: disgard and read from the database
profile_form = ProfileForm(instance=profile_object)
messages.error(request, 'Failed profile update.')
# user_form
if 'btn-accountdeactivation-submit' in request.POST:
profile_form = ProfileForm(instance=profile_object)
# validate form
if user_form.is_valid():
# valid: delete user from database
cd = user_form.cleaned_data
print(cd.get('accountdeactivation'))
User = get_user_model()
user_pk = request.user.pk
auth_logout(request)
User.objects.filter(pk=user_pk).delete()
messages.error(request, 'Successful account deactivation.')
return render(request, "home.html", context)
else:
# invalid: disgard and warn the user
messages.error(request, 'Failed account deactivation. You must confirm your account deactivation.')
context["profile_form"] = profile_form
context["user_form"] = user_form
return render(request, "profile.html", context)

Django messages not showing up on redirects, only render

For a couple days now, I've been trying to figure out why my messages don't show up on redirects. All of the dependencies are there in my settings.py file as you can see. I don't think that's the problem because I am getting two messages to show up on signup and login if the user's passwords don't match on signup or if the user enters the wrong password on login. I notice it only works on renders, but not on redirects. I'll post an image of my file structure and also the relevant files next.
File structure images:
settings.py
from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
messages.DEBUG: 'alert-info',
messages.INFO: 'alert-info',
messages.SUCCESS: 'alert-success',
messages.WARNING: 'alert-warning',
messages.ERROR: 'alert-danger',
}
INSTALLED_APPS = [
...
'django.contrib.messages',
...
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
'django.contrib.messages.middleware.MessageMiddleware',
...
]
TEMPLATES = [
...
'context_processors': [
...
'django.contrib.messages.context_processors.messages',
],
},
},
]
My urls.py in the main virtual_library folder
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from book.views import *
urlpatterns = [
path('admin/', admin.site.urls),
# Book paths
path('', include('book.urls')),
# Added Django authentication system after adding members app
path('members/', include('django.contrib.auth.urls')),
path('members/', include('members.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My urls.py in the book folder
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from .views import *
from book import views
urlpatterns = [
# Default path
path('', views.home, name='home'),
# Book paths
path('create/', views.createbook, name='createbook'),
path('current/', views.currentbooks, name='currentbooks'),
path('wanttoread/', views.wanttoreadbooks, name='wanttoreadbooks'),
path('currentlyreading/', views.currentlyreading, name='currentlyreading'),
path('read/', views.read, name='read'),
path('book/<int:book_pk>', views.viewbook, name='viewbook'),
path('book/<int:book_pk>/editbook', views.editbook, name='editbook'),
path('book/<int:book_pk>/viewonly', views.viewonly, name='viewonly'),
path('book/<int:book_pk>/delete', views.deletebook, name='deletebook'),
# Genres
path('genre/', AddGenreView.as_view(), name='addgenre'),
]
My urls.py in the members folder
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.contrib.auth import views as auth_views
from django.conf.urls.static import static
from members import views
from . import views
from .views import UserEditView, CreateProfilePageView, ShowProfilePageView, EditProfilePageView, PasswordsChangeView
urlpatterns = [
# User auth
path('signupuser/', views.signupuser, name='signupuser'),
path('loginuser/', views.loginuser, name='loginuser'),
path('logoutuser/', views.logoutuser, name='logoutuser'),
# User settings
path('edit_settings/', UserEditView.as_view(), name='edit_settings'),
# path('password/', auth_views.PasswordChangeView.as_view(template_name='registration/change_password.html')),
path('password/', PasswordsChangeView.as_view(template_name='registration/change_password.html')),
path('password_success/', views.password_success, name="password_success"),
# User profile
path('create_profile_page/', CreateProfilePageView.as_view(), name='create_profile_page'),
path('<int:pk>/edit_profile_page/', EditProfilePageView.as_view(), name='edit_profile_page'),
path('<int:pk>/profile/', ShowProfilePageView.as_view(), name='show_profile_page'),
]
base.html in the book folder
<div class="container mt-5">
{% for message in messages %}
<div class="container-fluid p-0">
<div class="alert {{ message.tags }} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button> {{ message }}
</div>
</div>
{% endfor %} {% block content %}{% endblock %}
</div>
my currentbooks.html template to view user's books in the book folder
{% extends "book/base.html" %} {% load static %} { % block title % } Your Books { % endblock % } {% block content %}
<div class="row justify-content-center mt-5">
<div class="col-md-10">
<h1>{% if book_list %} {{ book_list.count }} total book{{ book_list.count|pluralize }} in your Mibrary...</h1>
</div>
</div>
<div class="row justify-content-center mt-5">
<div class="col-md-10">
{% if page_obj %}
<div class="container mt-1">
{% for book in page_obj %}
<div class="card-body">
{% if book.book_img %}
<img src="{{ book.book_img.url }}" alt="{{ book.title }}" class="img-fluid" style="height:150px; width:100px"> {% else %}
<img src="{% static 'book/images/logo.png' %}" alt="{{ book.title }}" class="img-fluid" style="height:150px; width:100px"> {% endif %}
<blockquote class="blockquote mt-3">
<a href="{% url 'viewonly' book.id %}">
<strong><p class="mb-0">{{ book.title|capfirst }}</p></strong>
</a>
<p class="mb-0">{% if book.summary %}{{ book.summary|truncatechars:80|safe }}{% endif %}</p>
</blockquote>
<footer class="blockquote-footer">by <cite title="Source Title">{{ book.author }}</cite></footer>
<small><p class="mb-0"><em>{{ book.user }}</em></p></small>
</div>
<hr> {% endfor %}
<div class="pagination">
<span class="step-links mr-2">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current mr-2">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span> {% if page_obj.has_next %}
next
last » {% endif %}
</span>
</div>
</div>
{% endif %} {% else %}
<div class="row">
<div class="col mt-5">
<a role="button" class="btn btn-outline-primary btn-lg" href="{% url 'createbook' %}">Add book</a>
</div>
<div class="col">
<h2>You haven't added any books yet...</h2>
<br>
<img src="../static/book/images/reading-list.svg" class="img-fluid mt-3" style="width:400px;" alt="Responsive image" title="stack of books">
</div>
</div>
</div>
{% endif %} {% endblock %}
views.py for currentbooks
from django.contrib import messages
...
#login_required
def currentbooks(request):
book_list = Book.objects.filter(user=request.user)
paginator = Paginator(book_list, 2)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'book/currentbooks.html', {'page_obj': page_obj, 'book_list': book_list})
my createbook.html to add books in the book folder
{% extends 'book/base.html' %} {% block title %} Add Book{% endblock %} {% block content %}
<div class="container mt-5">
<h1>Create Book...</h1>
</div>
<div class="form-group mt-3">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %} {{ error }} {{ form.media }} {{ form.as_p }}
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-outline-warning" onclick="$('#cancel').click()">Cancel</button>
</form>
<form style='display: none;' method="POST" action="{% url 'currentbooks' %}">
{% csrf_token %}
<button id="cancel" type="submit">Cancel</button>
</form>
</form>
</div>
{% endblock %}
My editbook.html view to delete in the book folder
{% extends "book/base.html" %} {% block title %} Edit Book {% endblock %} {% block content %} {% if user.id == book.user_id %}
<div class="container mt-5">
<h1>Edit Book...</h1>
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
</div>
<div class="form-group mt-3">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %} {{ form.media }} {{ form.as_p }}
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-warning" onclick="$('#cancel').click()">Cancel</button>
<button type="button" class="btn btn-danger" onclick="$('#delete').click()">Delete</button>
</form>
<form style='display: none;' method="POST" action="{% url 'deletebook' book.id %}">
{% csrf_token %}
<button id="delete" type="submit">Delete</button>
</form>
<form style='display: none;' method="POST" action="{% url 'currentbooks' %}">
{% csrf_token %}
<button id="cancel" type="submit">Cancel</button>
</form>
</div>
{% else %}
<div class="row justify-content-center mt-5">
<h1>You are not allowed to edit this book...</h1>
</div>
{% endif %} {% endblock %}
views.py in the book folder
from django.contrib import messages
...
# Create
#login_required
def createbook(request):
if request.method == 'GET':
form = BookForm()
return render(request, 'book/createbook.html', {'form': form})
else:
try:
form = BookForm(request.POST, request.FILES)
newbook = form.save(commit=False)
newbook.user = request.user
if form.is_valid():
newbook.save()
# This message does not show up under the redirect
messages.success(request, 'Book saved!')
return redirect('currentbooks')
except ValueError:
messages.error(request, 'Bad data passed in. Try again.')
return render(request, 'book/createbook.html', {'form':BookForm()})
# Delete
#login_required
def deletebook(request, book_pk):
book = get_object_or_404(Book, pk=book_pk, user=request.user)
if request.method == 'POST':
book.delete()
# This message does not show up under redirect
messages.info(request, 'Book deleted!')
return redirect('currentbooks')
My loginuser.html to login in the members folder
{% extends 'book/base.html' %} {% block title %} Login {% endblock %} {% block content %}
<div class="container">
<h1>User Login...</h1>
<div class="row">
<div class="col mt-5">
<form method="POST">
<div class="form-group">
{% csrf_token %} {{ error }}
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" id="username" aria-describedby="usernameHelp">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-outline-danger btn-lg">Sign In</button>
</div>
</form>
</div>
<div class="col">
<img src="../../static/book/images/studying.svg" class="img-fluid" alt="Responsive image" title="woman reading II">
</div>
</div>
</div>
{% endblock %}
views.py in the members folder
from django.shortcuts import render, redirect, get_object_or_404, HttpResponseRedirect
...
from django.contrib import messages
...
# Auth functions
def signupuser(request):
if request.method == 'GET':
return render(request, 'registration/signupuser.html', {'form':UserCreationForm()})
else:
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.create_user(request.POST['username'], password=request.POST['password1'])
user.save()
login(request, user)
# This message does not show in the redirect
messages.success(request, 'User successfully created.')
return redirect('currentbooks')
except IntegrityError:
return render(request, 'registration/signupuser.html', {'form':UserCreationForm()})
else:
# This message does show up under render
messages.error(request, 'Passwords do not match.')
return render(request, 'registration/signupuser.html', {'form':UserCreationForm()})
def loginuser(request):
if request.method == 'GET':
return render(request, 'registration/loginuser.html', {'form':AuthenticationForm()})
else:
user = authenticate(request, username=request.POST['username'], password=request.POST['password'])
if user is None:
messages.error(request, 'Username and password do not match.')
# This message does show up under render
return render(request, 'registration/loginuser.html', {'form':AuthenticationForm()})
else:
login(request, user)
# This message does not show up under redirect
messages.success(request, 'Logged in successfully.')
return redirect('currentbooks')
#login_required
def logoutuser(request):
if request.method == 'POST':
logout(request)
# This message does not show up. I tried HttpResponseRedirect as a last option.
messages.success(request, 'Logged out successfully!')
return HttpResponseRedirect(reverse_lazy('loginuser'))
So ultimately, the messages don't seem to work with redirects, but they do work if I render and declare the folder and template name. Otherwise, no message displays if there is a redirect. I'm not quite sure what is wrong or why redirects are not working with these messages.
Matt Gleason's answer is incorrect, because messages framework doesn't store it in request object: https://docs.djangoproject.com/en/3.2/ref/contrib/messages/#storage-backends
Messages do work with redirects just fine out of the box. Check if everything is OK with your cookies (it's a default storage)

Django redirect to specific URL after Registration

Good day.
I'm trying to redirect a user to specific url which in my case is rootPath/dashboard/
But when the user registers i get redirected to /user/register/dashboard/
I have searched other stackoverflow topics on same problem but they didn't resolve my problem.
I have defined these settings in settings.py
LOGIN_URL = 'user/login/'
LOGOUT_URL = 'user/logout/'
LOGIN_REDIRECT_URL = 'dashboard/'
views.py
def register(request):
form = RegisterForm(request.POST or None)
if request.POST:
if form.is_valid():
data = form.cleaned_data
email = data['email']
pwd = data['password']
user = User(email=email, password=pwd)
user.save()
return redirect(settings.LOGIN_REDIRECT_URL)
return render(request, 'registration/register.html', context={'form': form})
#login_required
def dashboard(request):
return render(request, 'user/dashboard.html')
urls.py
urlpatterns = [
path('user/login/', CustomLoginView.as_view(), name='login'),
path('user/logout/', auth_logout, name='logout'),
path('user/register/', register, name='register'),
path('dashboard/', dashboard, name='dashboard')
]
register.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="container text-center">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Register</h1>
<form class="form-signin" action="." method="post">
{{ form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Register" class="btn btn-primary"></p>
{# <input type="button" value="Forgot Password">#}
</form>
</div>
{% endblock %}
You can redirect to any specific url with redirect like this
return redirect('dashboard') #return redirect('url_name')
if the app_name is provided it would be like this
return redirect('app_name:url_name')

Django form not rendered by auth_views.LoginView

I have a problem that is that Django is not rendering one of the fields of my Login form. I'm using the auth_views.LoginView view for user authentication, and even if I put my template, one of the fields does not appear in my html.
Url.py:
from django.urls import path, re_path
from django.contrib.auth import views as auth_views
from Turnos import views
urlpatterns = [
path('', views.home, name='home'),
with views.login view it works perfectly
#path('login/', views.login, name='login'),
with auth_views.LoginView.as_view(template_name='login.html') doesn't render the email field
path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
]
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth import login as auth_login
from Turnos.forms import loginForm
def login(request):
if request.method == 'POST':
form = loginForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request, user)
return redirect('nuevoTurno.html')
else:
form = loginForm()
return render(request, 'login.html', {'form': form})
forms.py:
from django import forms
from django.contrib.auth.models import User
class loginForm(forms.ModelForm):
email = forms.EmailField(required=True, widget=forms.EmailInput())
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['email', 'password']
Html:
<form action="/login/" method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="{{ form.email.label }}" class="">Email</label>
{% render_field form.email class+="form_control form-control-lg" placeholder="Email" %}
</div>
<div class="form-group">
<label for="{{ form.password.label }}" class="">Password</label>
{% render_field form.password placeholder="Password" class+="form_control form-control-lg" %}
</div>
<div class="form-group">
<button type="submit" class="btn btn-outline-light btn-block">
Enviar
</button>
</div>
<div class="form-group">
Lost password?
</div>
</form>
the email field is not displayed with auth_views.loginview
sorry for my English.
It looks like you're using a third part plugin to render individual form fields (I assume you have used {% load widget_tweaks %} in your base.html template.
Perhaps try:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
...or...
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
Or even...
{{ form.non_field_errors }}
<div class="form-group">
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">Email</label>
{{ form.email }}
</div>
If the above doesn't work, then it is time to debug why email isn't pulling through. Not sure if it's an ordering thing (unlikely):
email = forms.EmailField(widget=forms.EmailInput(), attrs={'class': "form_control form-control-lg", 'placeholder': "Email"}, required=True, )
^ I've also added the Django way of passing in attributes to your form fields.

How to have user log in and registration on same page using django

Currently I have a user log in page and a user sign up page, how can I have both of these on one single page?
Base.html:
<!doctype html>
<head>
{% block head %}
<title>base</title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
signup.html:
{% extends 'core/base.html' %}
{% block head %}
<title> Sign Up</title>
{% endblock %}
{% block body %}
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}
login.html:
{% extends 'core/base.html' %}
{% block head %}
<title> Login</title>
{% endblock %}
{% block body %}
<h1>Login</h1>
<form method = 'post'>
{% csrf_token %}
{{ form.as_p }} <!--'form' comes from login view imported in urls-->
<button type = 'submit'>Login</button>
</form>
{% endblock %}
urls.py:
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.views import login
from core import views as core_views
urlpatterns = [
url(r'^$', core_views.login_redirect, name = 'login_redirect'),
url(r'^admin/', admin.site.urls),
url(r'^login/$', login, {'template_name': 'core/login.html'}, name='login'),
url(r'^signup/$', core_views.signup, name='signup'),
url(r'^account/$', core_views.account_page, name = 'account_page')
]
views.py:
from django.shortcuts import render
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.forms import UserCreationForm
def login_redirect(request):
return redirect('login')
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/account')
else:
form = UserCreationForm()
args = {'form': form}
return render(request, 'core/signup.html', args)
def account_page(request):
return HttpResponse('success')
How would I put both the log in and sign up on one page, if they are handled by separate views? Thank you in advance for your response! I have no more details to add and it is making me add more details i apologize for this unnecessary text.
In any scenario where you need multiple forms in the same page the following technique can be applied.
For example currently you need two forms 'Sign In' and 'Sign Up' on the same page.
index.html
<!-- Sign In Form -->
<form>
<button type='submit' name='submit' value='sign_in'></button>
</form>
<!-- Sign Up Form -->
<form>
<button type='submit' name='submit' value='sign_up'></button>
</form>
views.py
def index(request):
if request.method == "POST":
if request.POST.get('submit') == 'sign_in':
# your sign in logic goes here
elif request.POST.get('submit') == 'sign_up':
# your sign up logic goes here