Django's authentication form is always not valid - django

I was trying to implement a basic login system using Django with a custom user using the AbstractUser class.
Here is my models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
class Stock(models.Model):
stock_name = models.CharField(max_length=10)
stock_price = models.FloatField()
def __str__(self):
return self.stock_name
class CustomUser(AbstractUser):
stocks = models.ManyToManyField(Stock)
def __str__(self):
return self.username
My forms.py:
from .models import CustomUser,Stock
from django.contrib.auth.forms import AuthenticationForm
class loginform(AuthenticationForm):
class Meta:
model = CustomUser
fields = ('username', 'password')
My views.py:
def successful_login(request, pk):
user = get_object_or_404(CustomUser, pk=pk)
return render(request, '../templates/stock_portfolio.html', {'user':user})
def loginview(request):
err=0
if request.method=="POST":
form = loginform(request.POST)
pdb.set_trace()
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
pdb.set_trace()
login(request, user)
pk = user.id
pdb.set_trace()
return redirect('successful_login', pk=pk)
else:
err=1
return render(request,'../templates/login.html',{'response':err,'form':form})
else:
form = loginform()
return render(request, '../templates/login.html',{'form':form})
While logging using pdb here is what I am getting for the form.
<loginform bound=False, valid=Unknown, fields=(username;password)>
How do I proceed now?

Answering this since I just had the same issue and found the problem. Change your
form = loginform(request.POST)
to
form = loginform(data=request.POST)
Worked like a charm for me.

Related

ValueError at /profile/ ModelForm has no model class specified. Error django

Iam coding in django and trying to figure how to update profile of a user in my app
Please help me Iam trying to learn how to code and this is a big barrier for me to learn
here's models.py:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete= models.CASCADE)
image = models.ImageField(default='default.jpg',upload_to="profile_pics")
def __str__(self):
return f'{self.user.username} Profile'
here's my views.py:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get("username")
messages.success(request, f'Yor account has been created! You are now able to login')
return redirect('/login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html',{'form': form})
#login_required
def profile(request):
u_form = UserUpdateForm(instance = request.user)
p_form = ProfileUpdateForm(instance= request.user.profile)
context = {
'u_form': u_form,
'p_form': p_form
}
return render(request, 'users/profile.html', context)
Iam getting error at 'u_form':u_form,
and This is my forms.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email','password1','password2']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email']
class ProfileUpdateForm(forms.ModelForm):
model = Profile
field = ['image']
Iam getting my error at this
p_form = ProfileUpdateForm()
In the ProfileUpdateForm you defined the model class name without the Meta class
Model name and fields should be defined inside the Meta class like this:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']

Django CRUD - create and update view doesn't work

I'm really new to Django and I want to teach myself by making a simple note. I maked a simple form for creating a new note but I don't know how to make this just for the user is logged in. What I mean is that I want the user field from the creationNoteForm to be removed and the note to be sumbitted automatically for the person who is logged in. Hope that I was clear enough.
Here is my "view.py":
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)
#login_required(login_url='login')
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 = {
'form': form,
}
return render(request, 'accounts/create_note.html', context)
def deleteNote(request, pk):
note = Note.objects.get(id=pk)
if request.method == 'POST':
note.delete()
return redirect('notes')
context = {'note': note}
return render(request, 'accounts/delete.html', context)
def updateNote(request, pk):
note = Note.objects.get(id=pk)
form = CreateNoteForm(instance=note)
if request.method == 'POST':
form = CreateNoteForm(request.POST, instance=note)
if form.is_valid():
form.save()
return redirect('notes')
context = {'form': form, 'note': note}
return render(request, 'accounts/update.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 "models.py" just in case:
from django.db import models
from django.contrib.auth.models import User
class Note(models.Model):
#user = models.ForeignKey(Person, null=True, on_delete=models.SET_NULL)
user = models.ForeignKey(User, null=True,on_delete=models.SET_NULL)
title = models.CharField(max_length=200, null=True)
text = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Thank you and sorry I am a noob!

Django, data forms cannot be saved

I have a problem with Django when I would like to get information from the register. I can get their first name, last name, and email but no nickname and graduated schools. I thought i did it correctly since i added nickname and school inside forms.py
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm):
first_name = forms.CharField()
last_name = forms.CharField()
nickname = forms.CharField()
school = forms.CharField()
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'password1', 'password2',
'first_name', 'last_name', 'nickname', 'school']
class UserUpdateForm(forms.ModelForm):
first_name = forms.CharField()
last_name = forms.CharField()
nickname = forms.CharField()
school = forms.CharField()
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email','first_name', 'last_name', 'nickname', 'school']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
models.py
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300,300)
img.thumbnail(output_size)
img.save(self.image.path)
views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get['username']
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
#login_required
def profile(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('profile')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
context = {
'u_form': u_form,
'p_form': p_form
}
return render(request, 'users/profile.html', context)
I have tried to save by adding form.cleaned_data.get in views.py but it still didn't work. I appreciate all help.
The problem is that you are not saving "nickname" and "graduated schools" to any model(based on models.py). First of all, you are inheriting from the user model when you do the following:
'''
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
'''
In doing so you can only save what you have in the Profile model and the User model, which I would recommend reading https://docs.djangoproject.com/en/2.1/ref/contrib/auth/ detailing what does the User model have(username,password, etc.).
Lastly, I would just add the nickname and the graduated schools to the Profile Model and it should work.

NOT NULL constraint failed: core_profile.user_id

I have a model named Profile which is created to extend the User auth model. I have created two forms one is UserForm and ProfileForm. In register.html template I show this two forms and wish to save in the database through the user.
But it constantly shows the exception: Integrity Error
NOT NULL constraint failed: core_profile.user_id
whenever I try to submit the post filling out all the fields and hit submit button.
Here are my models:
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
And here is my view for posting the forms:
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from .forms import SignUpForm, ProfileForm
#login_required
def home(request):
return render(request, 'home.html')
def signup(request):
if request.method == 'POST':
user_form = SignUpForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid():
user = user_form.save()
profile_form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.profile.birth_date = user_form.cleaned_data.get('birth_date')
user.save()
raw_password = user_form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('home')
else:
user_form = SignUpForm()
profile_form = ProfileForm()
return render(request, 'signup.html', {'user_form': user_form, 'profile_form': profile_form})
And here are the forms:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Profile
class SignUpForm(UserCreationForm):
birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')
class Meta:
model = User
fields = ('username', 'password1', 'password2', 'birth_date')
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('bio', 'location')
Thank you,
When you are trying to save the profile_form, it doesn't know to which user it is related to. And in your case, when you save the user form, it will create the profile, and what you need to do is just update the profile of you saved user, so I suggest something like:
def signup(request):
if request.method == 'POST':
user_form = SignUpForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid():
user = user_form.save()
user.profile.bio = profile_form.cleaned_data.get('bio')
user.profile.location = profile_form.cleaned_data.get('location')
user.profile.save()
...
In addition to #Gagik Sukiasyan's answer: I added some additional things to reduce errors / ease your life:
transaction.atomic -> if errors occur, the database is being rolled back
and profile_form.is_valid() makes sure profile_form is validated
instead of going through the profile attributes manually I added a loop
Modified Code:
from django.db import transaction
#transaction.atomic
def register(request):
""" register a new user view """
if request.method == 'POST':
user_form = UserRegisterForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
for field in profile_form.changed_data:
setattr(user.profile, field, profile_form.cleaned_data.get(field))
user.profile.save()

Editing a userprofile on django

How to create a userprofile editable page and upon clicking submission it updates the details provided during registration(the details stored in the database) using DJANGO?.
Creation of registration form for a user, and like i have said in my opening post, i want the user after he must have logged in to able to edit what he provided during registration and it will update the previous details stored in the database.
I know i need to create a view for it, but have not arrived at how to call on the details provided during registration. Well maybe using user.get_profile()
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from registeredmember.models import Registeredmember
class RegistrationForm(ModelForm):
first_name = forms.CharField(label=(u'First Name'))
middle_name = forms.CharField(label=(u'Middle Name'))
last_name = forms.CharField(label=(u'Last Name'))
occupation = forms.CharField(label=(u'Occupation'))
income = forms.IntegerField(label=(u'Income Amount'))
age = forms.IntegerField(label=(u'Age'))
address_line1 = forms.CharField(label=(u'Address line 1'))
address_line2 = forms.CharField(label=(u'Address line 2'))
city = forms.CharField(label=(u'City'))
state = forms.CharField(label=(u'State'))
phone_no_Mobile = forms.IntegerField(label=(u'Phone Number (Home)'))
phone_no_Work = forms.IntegerField(label=(u'Phone Number (Work)'))
purpose = forms.CharField(label=(u'Purpose'))
username = forms.CharField(label=(u'Username'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput)
password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput)
class Meta:
model = Registeredmember
exclude = ('user','reference_number',)
def clean_username(self):
username = self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError('That username is already taken, please select another.')
def clean_email(self):
email = self.cleaned_data['email']
try:
User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError('That email address is already in the database, please provide another.')
class LoginForm(forms.Form):
username = forms.CharField(label=(u'Username'),widget=forms.TextInput(attrs={'size': '30'}))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput)
views.py
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.template import RequestContext
from registeredmember.forms import RegistrationForm, LoginForm
from registeredmember.models import Registeredmember
from django.contrib.auth import authenticate, login, logout
import random, time
from random import randint
def userregistration(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == 'POST':
form = RegistrationForm
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(username=form.cleaned_data['username'], email = form.cleaned_data['email'], password = form.cleaned_data['password'])
user.first_name = form.cleaned_data['first_name']
user.last_name = form.cleaned_data['last_name']
user.save()
registeredmember = Registeredmember(user=user, prefix = form.cleaned_data['prefix'],first_name=form.cleaned_data['first_name'],\
middle_name=form.cleaned_data['middle_name'],last_name=form.cleaned_data['last_name'],gender=form.cleaned_data['gender'],\
occupation=form.cleaned_data['occupation'],income=form.cleaned_data['income'],age=form.cleaned_data['age'],\
address_line1=form.cleaned_data['address_line1'],address_line2=form.cleaned_data['address_line2'],city=form.cleaned_data['city'],\
state=form.cleaned_data['state'],phone_no_Mobile=form.cleaned_data['phone_no_Mobile'],phone_no_Work=form.cleaned_data['phone_no_Work'],\
purpose=form.cleaned_data['purpose'])
registeredmember.save()
return render_to_response('carloan/regsuccessful.html',{'ref_no': ref_no}, context_instance=RequestContext(request))
else:
return render_to_response('carloan/register.html', {'form': form}, context_instance=RequestContext(request))
else:
'''user is not submitting the form, show them a blank registration form'''
form = RegistrationForm()
return render_to_response('carloan/register.html', {'form': form}, context_instance=RequestContext(request))
#login_required
def Profile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
registeredmember = request.user.get_profile
return render_to_response('carloan/profile.html', {'registeredmember': registeredmember}, context_instance=RequestContext(request))
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method =='POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
registeredmember = authenticate(username=username, password=password)
if registeredmember is not None:
login(request, registeredmember)
return HttpResponseRedirect('/profile/')
else:
return render_to_response('carloan/loginerror.html', context_instance=RequestContext(request))
else:
'''user is submitting a blank login form, notify him that he submitted a blank form'''
return render_to_response('carloan/loginblank.html', context_instance=RequestContext(request))
else:
'''user is not submitting the form, show the login form'''
form = LoginForm()
return render_to_response('carloan/login.html',{'form': form}, context_instance=RequestContext(request))
def LogoutRequest(request):
logout(request)
return render_to_response('carloan/logout.html', context_instance=RequestContext(request))
The code below gives the error username already exists, but when i specify a new username it updates although it doesn't update the username but the other fields
views.py for the editprofile
#login_required
def editprofile(request):
registeredmember = request.user.get_profile()
if request.method == 'POST':
userprofile_edit = RegistrationForm(request.POST, instance = registeredmember)
if userprofile_edit.is_valid():
userprofile_edit.save()
return HttpResponseRedirect('/profile/')
else:
userprofile_edit = RegistrationForm(instance = registeredmember)
return render_to_response('carloan/editprofile.html', {'userprofile_edit': userprofile_edit}, context_instance=RequestContext(request))
Got it sorted out with codes below:
forms.py
class EditForm(forms.ModelForm):
class Meta:
model = Registeredmember
exclude = ('user','username','email','password','password1',)
views.py
#login_required
def editprofile(request):
if request.method == 'POST':
userprofile_edit = EditForm(request.POST, instance = request.user.get_profile())
if userprofile_edit.is_valid():
userprofile_edit.save()
return HttpResponseRedirect('/profile/')
else:
userprofile_edit = EditForm(instance = request.user.get_profile())
return render_to_response('carloan/editprofile.html', {'userprofile_edit': userprofile_edit}, context_instance=RequestContext(request))
Thank you all...
Django 1.5 and custom user models will help with this, but in the mean time your ModelForm set up is fine.
To initialize a ModelForm from an instance of its object, do this:
user_profile_form = RegistrationForm(request.POST, instance=request.user.get_profile())
The request.POST in that line allows you to update the user_profile_form object with the user's input. It will nicely merge the existing data from your instance with the new info from the user.
You can then print this to a view, or you can save it doing this:
if user_profile_form.is_valid():
user_profile_form.save()
else
# do other stuff