how to implement AuthenticationForm in a view? - django

forms.py:
from django import forms
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.utils.text import capfirst
from .models import Classname, Sectionname, Teachername, Attendancename
class AuthenticationForm(forms.Form):
username = forms.CharField(max_length=20)
password = forms.CharField(widget=forms.PasswordInput)
error_messages = {
'invalid_login': ("Please enter a correct %(username)s and password."
"Note that both fields may be case-sensitive."),
'inactive': ("This account is inactive"),
}
def __init__(self, request=None, *args, **kwargs):
self.request = request
self.user_cache = None
super(AuthenticationForm, self).__init__(*args, **kwargs)
UserModel = get_user_model()
self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
if self.fields['username'].label is None:
self.fields['username'].label = capfirst(self.username_field.verbose_name)
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username and password:
self.user_cache = authenticate(username=username, password=password)
if self.user_cache is None:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
views.py:
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.template.response import TemplateResponse
from django.views.generic import DeleteView, ListView
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.cache import never_cache
from .models import Classname, Sectionname, Teachername, Attendancename
from .forms import ClassnameForm, SectionnameForm, TeachernameForm, AttendancenameForm, UserForm, PasswordChangeForm, AuthenticationForm
def user_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
login(request, user)
return HttpResponseRedirect(reverse('student:mains'))
else:
return HttpResponse("Invalid Login details supplied!")
return render(request, 'login.html', {'form': form},)
my template:
<html>
<head><title>Login</title></head>
<strong> Mysite Login </strong>
<br><br>
<h3> Please Enter your credentials carefully </h3>
<body>
{% if form.errors %}
<p>NOT VALID</p>
{% for errors in form.errors %}
{{ errors }}
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<label>Username: </label>
<input type="text">
<br>
<label>Password: </label>
<input type="password">
<br>
<input type="submit" value="Login">
</form>
</body>
</html>
Here above I'm trying to implement authentications on my current app. I want to show login failure error on same login page, For which I have written a 'AuthenticationForm' class above.
I read some docs but don't know exactly how to use this form in my views for Authentication purpose.
Please! Can anybody suggest me how to make it correct

Related

Django - UserEditView is missing a QuerySet?

trying to create an edit profile for users and i keep getting this error what should i add or change ? is my models right for UserEditView
this is my views.py (all of it edited)
maybe the vendor its not compatitable with User edit view
anything elses needs to be added or should i just change something
all imports are for vendor and UserEditView
from tkinter import Entry
from django.contrib.auth.models import User
from xml.dom.minidom import Entity
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
from django.views import generic
from django.contrib.auth.forms import UserCreationForm , UserChangeForm
from django.utils.text import slugify
from django.shortcuts import render, redirect
from .models import Profile, Vendor
from products.models import Product
from .forms import ProductForm
# Create your views here.
def become_vendor(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
vendor = Vendor.objects.create(name=user.username, created_by=user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'vendor/become_vendor.html', {'form': form})
#login_required
def vendor_admin(request):
context = {
'user':request.user
}
vendor = request.user.vendor
products = vendor.products.all()
return render(request,'vendor/vendor_admin.html',{'vendor': vendor , 'products': products ,'context':context})
#login_required
def add_house(request):
if request.method == 'POST':
form = ProductForm (request.POST, request.FILES)
if form.is_valid():
product = form.save(commit=False)
product.vendor = request.user.vendor
product.slug = slugify(product.عنوان)
product.save()
return redirect('vendor_admin')
else:
form = ProductForm()
return render(request,'vendor/add_house.html',{'form': form})
class UserEditView(generic.UpdateView):
models = User
form_class = UserChangeForm
template_name = 'vendor/edit_profile.html'
seccess_url = reverse_lazy('vendor_admin')
def get_object(self):
return self.request.user
urls.py
from django.urls import path
from .import views
from .views import UserEditView
from django.contrib import admin
from django.contrib.auth import views as auth_views
urlpattern =[
path('signup/', views.become_vendor, name='become_vendor'),
path('profile/', views.vendor_admin, name='vendor_admin'),
path("logout/", auth_views.LogoutView.as_view(), name="logout"),
path('login/', auth_views.LoginView.as_view(template_name='vendor/login.html'), name='login'),
path('edit_profile/', UserEditView.as_view(template_name='vendor/edit_profile.html'), name='edit_profile'),
]
edit_profile.html
(where the error pops up)
{% extends "base.html"%}
{% load static %}
{% block content %}
<title>title</title>
<div class="section pt-9 pb-9">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="section-title">
<div class="wrap-title">
<h3 class="title">
<span class="first-word"></span>
</h3>
<br>
<form method="post" >
{% csrf_token %}
<table>
{{ form.as_p }}
</table>
<button class='button'>Update</button>
</form>
</div>
<hr>
{% endblock content %}
I think that you didn't declare your model correctly:
class UserEditView(generic.UpdateView):
# models = UserChangeForm #That has no sense.
model = User #The name of your model (Probably the default one: User).
form_class = UserChangeForm
template_name = 'vendor/edit_profile.html'
success_url = reverse_lazy('vendor_admin')
def get_object(self):
return self.request.user
Other thing. You have declared your template name twice. According to your views.py you can delete the template_name on your urls.py:
path('edit_profile/', UserEditView.as_view(), name='edit_profile'),

Profile is not getting created for the new user after extension of the user model

Before extending the user module, I was easily able to register new users and the page would get redirected to the login page. Now on registering new users, the profile is not getting created and the page is also not getting redirected. The new user does get created though and sometimes the error is object does not exist, user profile does not exist, and sometimes the error is forbidden, csrf verification failed. I dont know where I'm going wrong. existing users are able to login and update profiles but new users I'm having a problem with.
Models.py is:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User,null= True ,on_delete= models.CASCADE)
profile_pic = models.ImageField(null = True, blank= True)
first = models.CharField(max_length=500, null=True)
last = models.CharField(max_length=500, null=True)
email = models.CharField(max_length=500, null=True)
mobile_number = models.IntegerField(null=True)
location = models.CharField(max_length= 500, null= True)
postal = models.IntegerField(null=True)
def __str__(self):
return self.first
My forms.py is:
from django.forms import ModelForm, fields
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from .models import *
class CreateUserForm(UserCreationForm):
email = forms.EmailField()
password2 = None
class Meta:
model = User
fields = ['username','first_name', 'last_name','email', 'password1']
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = '__all__'
exclude = ['user']
widgets = {
'profile_pic': forms.FileInput()
}
views.py is (I removed the login and logout view cause that was working fine):
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from .forms import CreateUserForm, ProfileForm
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from .models import *
def RegisterPage(request):
if request.user.is_authenticated:
return redirect('Profile')
else:
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
name = form.cleaned_data.get('first_name')
messages.success(request, 'Account created for ' + name)
Profile.object.create(
user = user,
)
Profile.save()
return HttpResponseRedirect('/Login/')
else:
form = CreateUserForm()
context = {'form':form}
return render(request, 'register.html', context)
#login_required(login_url='Login')
def Profile(request):
profile = request.user.profile
form = ProfileForm(instance=profile)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'profile.html', context)
my register template:
<form class="" action="" method="post">
{% csrf_token %}
<p class="reg-field-title"><strong>Username*</strong></p>
<div class="forms">{{form.username}}</div>
<p class="reg-field-title"><strong>First Name*</strong></p>
<div class="forms">{{form.first_name}}</div>
<p class="reg-field-title"><strong>Last Name*</strong></p>
<div class="forms">{{form.last_name}}</div>
<p class="reg-field-title"><strong>Email-ID*</strong></p>
<div class="forms">{{form.email}}</div>
<p class="reg-field-title"><strong>Password*</strong></p>
<div class="forms">{{form.password1}}</div>
<button type="submit" class="btn btn-dark btn-lg col-lg-10 reg-btn">Register</button>
</form>
My login template:
<p class="login-reg">New to MedsPlain? <a class="log-reg-link" href="/Registration/">Register </a>here</p>
<hr> {% if next %}
<form class="" action='/Login/Profile/' method="post"> {% csrf_token %} {%else%}
<form class="" action="/Login/" method="post">
{% endif %} {% csrf_token %}
<p class="login-field-title"><strong>Username*</strong></p>
<input type="text" name="username" class="form-control col-lg-10 log-inp-field" placeholder="Enter Username" required>
<p class="login-field-title"><strong>Password*</strong></p>
<input type="password" name="password" class="form-control col-lg-10 log-inp-field" placeholder="Enter Password" required> {% for message in messages %}
<p id="messages">{{message}}</p>
{% endfor %}
<button type="submit" class="btn btn-dark btn-lg col-lg-10 log-btn">Log In</button>
</form>
I've tried everything as of now, but i don't understand the mistake. Can someone please guide me through cause at this moment i'm frustrated, on the verge of crying and don't understand what to do.
There are basically two problems here:
there is a view Profile, and thus this will override the reference to the Profile model; and
you do not create a model record with Model.object.create(), but with Model.objects.create().
I would advise that you rename your views in snake_case, and remove the wildcard import, this is often not a good idea:
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from .forms import CreateUserForm, ProfileForm
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from .models import Profile
def register_page(request):
if request.user.is_authenticated:
return redirect('Profile')
else:
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
Profile.objects.create(
user = user,
)
messages.success(request, 'Account created for {user.first_name}')
return HttpResponseRedirect('/Login/')
else:
form = CreateUserForm()
context = {'form': form }
return render(request, 'register.html', context)
#login_required(login_url='Login')
def profile(request):
profile = request.user.profile
form = ProfileForm(instance=profile)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'profile.html', context)
You will also need to update the urls.py to work with the renamed views.

Django forms - submitting the data isn't working

I'm really new to Django and I want to teach myself my making a simple note. But I don't understand how django forms work. I made simple template when I can display the user's notes and now I am trying to make a view when the user can add new notes to account using a simple form.
Here is my views.py file
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from .forms import CreateUserForm, CreateNoteForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import *
# Create your views here.
def loginPage(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.info(request, 'Username or pasword is incorrect')
context = {}
return render(request, 'accounts/login.html', context)
def registerPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
user = form.cleaned_data.get('username')
messages.success(request, 'Account was created for '+ user)
return redirect('home')
context = {'form': form}
return render(request, 'accounts/register.html', context)
def logoutUser(request):
logout(request)
return redirect('login')
#login_required(login_url='login')
def home(request):
if request.user.is_authenticated:
username = request.POST.get('username')
context = {'username': username}
return render(request, 'accounts/home.html', context)
def notes(request):
username = None
if request.user.is_authenticated:
username = request.user.username
user_id = request.user.pk
user_notes = Note.objects.filter(user=user_id)
context = {
'user_notes': user_notes,
'username': username,
#'user_id' : user_id,
}
return render(request, 'accounts/notes.html', context)
def createNote(request):
username = request.user.username
user_id = request.user.pk
user_notes = Note.objects.filter(user=user_id)
form = CreateNoteForm()
if request.method == 'POST':
form = CreateNoteForm(request.POST)
if form.is_valid():
form.save()
return redirect('notes')
context = {'user_notes': user_notes, 'form': form}
return render(request, 'accounts/create_note.html', context)
forms.py:
from django.forms import ModelForm
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Note
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class CreateNoteForm(forms.ModelForm):
class Meta:
model = Note
fields = ['user', 'title', 'text']
and create_note.html:
{% extends 'accounts/main.html' %}
{% load static %}
{% block content %}
<br>
<br>
<div class="container">
<div class="card text-white bg-dark mb-3">
<div class="container">
<form action="{% url 'notes' %}" method="POST">
<div class="card-body">
{% csrf_token %}
{{form}}
<input type="Submit" name="Submit">
</div>
</form>
</div>
</div>
</div>
{% endblock %}
The problem is the new note isn't added when I submit the data. And also if anyone have other suggestions for structuring my views or making this app better I am happy to read them and learn new ways of improving my project. Sorry for long post. I am really noob.

NoReverseMatch (Reverse for ' user_login' not found)

I have a django project called log and an application called basic_app. I created a register form but when I want to create a user_login, I get this error:
NoReverseMatch at /basic_app/user_login/
Reverse for ' user_login' not found. ' user_login' is not a valid view function or pattern name.
views.py:
from django.shortcuts import render
from basic_app.forms import UserForm, UserProfileInfoForm
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
# Create your views here.
def index(request):
return render(request, 'basic_app/index.html')
#login_required
def special(request):
return HttpResponse('You are loged in!')
#login_required
def user_logout(request):
logout(request)
return HttpResponseRedirect(reverse('index'))
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES[
'profile_pic'
]
profile.save()
registered = True
else:
print(user_form.errors, profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request, 'basic_app/registration.html',
{'user_form':user_form,
'profile_form':profile_form,
'registered':registered})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username = username, password = password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse('Account Not Active.')
else:
print('Someone tried to login and failed!')
print('username:{} and password:{}'.format(username, password))
return HttpResponse('invalid login details supplied!')
else:
return render(request, 'basic_app/login.html',{})
basic_app/urls.py:
from django.conf.urls import url
from basic_app import views
#TEMPLATE URLS
app_name = 'basic_app'
urlpatterns = [
url(r'^register/$', views.register, name='register'),
url(r'^user_login/$', views.user_login, name='user_login'),
log/urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from basic_app import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^admin/', admin.site.urls),
url(r'^basic_app/', include('basic_app.urls')),
url(r'^logout/$', views.user_logout, name='logout'),
url(r'special/', views.special, name='special')
login.html:
{% extends 'basic_app/basic.html' %}
{% block body_block %}
<div class="jumbotron">
<h1>Please Login: </h1>
<form action="{% url 'basic_app: user_login' %}" method="post">
{% csrf_token %}
<label for="username">Username:</label>
<input type="text" name="username" placeholder="Enter Username">
<label for="passwrod">Password:</label>
<input type="password" name="password">
<input type="submit" name="" value="Login">
</form>
</div>
{% endblock %}

Django form not displaying name and email fields

I am trying to learn how to use the User class and have made a form, but cant get it to display the email, first_name and last_name fields, I have the following code:
forms.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required = True)
class Meta:
model = User
fields = (
'username',
'email',
'first_name'
'password1',
'password2'
)
def save(self, commit = True):
user super(UserCreationForm, self).save(commit = False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.forms import UserCreationForm
def index(request):
return HttpResponse('index page')
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('accounts')
else:
form = UserCreationForm()
return render(request, 'accounts/register.html', {'form': form})
# Create your views here.
register.html:
{% extends 'accounts/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 %}
When I go to /accounts/register a form with username, password and password confirmation fields appear and the form works and saves to the database. But where are the first_name, last_name, email fields inlcuded in the User model?
Use RegistrationForm instead of UserCreationForm in your views
replace
from django.contrib.auth.forms import UserCreationForm
to
from .forms import RegistrationForm
form = RegistrationForm()