I wanted to insert the user details in auth_user table, but it gives the error of create_user() got an unexpected keyword argument 'first_name'
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from customer_reg.models import Customer
class Registration_Form(ModelForm):
first_name = forms.CharField(label=(u'First Name'))
last_name = forms.CharField(label=(u'Last Name'))
username = forms.CharField(label=(u'User Name'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
class Meta:
model=Customer
exclude=('user',)
def clean_username(self):
username=self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("The Username is already taken, please try another.")
def clean_password(self):
password=self.cleaned_data['password']
return password
views.py
from django.contrib.auth.models import User
from customer_reg.models import Customer
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from customer_reg.forms import Registration_Form
def CustomerRegistration(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/customer_profile/')
if request.method == 'POST':
form = Registration_Form(request.POST)
if form.is_valid():
user=User.objects.create_user(first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name'], username=form.cleaned_data['username'], email=form.cleaned_data['email'], password = form.cleaned_data['password'])
user.save()
customer=user.get_profile()
customer.birthday=form.cleaned_data['birthday']
customer.website=form.cleaned_data['website']
customer.store=form.cleaned_data['store']
customer.welcomemail=form.cleaned_data['welcomemail']
customer.save()
return HttpResponseRedirect('/customer_profile/')
else:
return render_to_response('customer_register.html',{'form':form} , context_instance=RequestContext(request))
else:
''' user is not submitting the form, show them a blank registration form '''
form = Registration_Form()
context={'form':form}
return render_to_response('customer_register.html',context , context_instance=RequestContext(request))
If I edit the views.py as
user=User.objects.create_user(username=form.cleaned_data['username'], email=form.cleaned_data['email'], password = form.cleaned_data['password'])
then it works successfully
I have already tried firstname as well as first_name
any idea where I have done the mistake
The create_user manager method only accepts three arguments, username, email (optional), and password (optional).
Once you have created a user, you can modify the other fields, then save again.
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()
If you want to be able to register using admin interface you gonna have to change the admin.py inside your app
Related
I've created a usercreationform and try to check if username and email is already exist in database or not. Here It only check for email if it is exist or not but it cannot check for the username.
Views.py
from django.shortcuts import render,redirect
from . forms import signupform
from django.contrib import messages
from django.contrib.auth import login,authenticate,logout
from django.contrib.auth.models import User
def signup_data(request):
form = signupform(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
if User.objects.filter(username=username).exists():
messages.error(request,'Username is already taken')
return redirect('signup')
elif User.objects.filter(email=email).exists():
messages.error(request,'Email is already taken')
return redirect('signup')
else:
form.save()
messages.success(request,'Account Is Created')
return redirect('signup')
return render(request,'login_module/signup.html',{'form':form, 'message': messages})
Forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User class signupform(UserCreationForm):
username= forms.CharField(max_length=10,widget=forms.TextInput(attrs={'class':'form-control'}))
first_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'class': 'form-control'}))
email = forms.EmailField(max_length=20,widget=forms.EmailInput(attrs={'class': 'form-control'}))
password1 = forms.CharField(label="Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2 = forms.CharField(label="Confirm Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields = ['username','first_name','last_name','email','password1','password2']
You can combine both the queries to run a OR query using Q for that:
from django.db.models import Q
if User.objects.filter(Q(username=username)|Q(email=email)).exists():
# do stuff
please read through my code, my question with screenshots and things i've already tried are after my code.
managers.py:
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, **extra_feilds):
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_feilds)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_feilds):
extra_feilds.setdefault('is_staff', True)
extra_feilds.setdefault('is_superuser', True)
extra_feilds.setdefault('is_active', True)
if extra_feilds.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff = True'))
if extra_feilds.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True'))
return self.create_user(email, password, **extra_feilds)
models.py:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=40)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser, StripeConnectSetup
from django import forms
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('email', 'first_name', 'last_name')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
views.py
from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm, CustomUserChangeForm, StripeConnectSetupForm
from .models import CustomUser
from django.contrib.auth import login, logout
from django.contrib.auth.forms import AuthenticationForm
def update_user_view(request):
obj = CustomUser.objects.get(email=request.user.email)
data = {'email': obj.email, 'first_name': obj.first_name, 'last_name': obj.last_name}
form = CustomUserChangeForm(initial=data)
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, request.FILES)
if form.is_valid():
obj = CustomUser.objects.get(email=request.user.email)
obj.email = form.cleaned_data['email']
obj.first_name = form.cleaned_data['first_name']
obj.last_name = form.cleaned_data['last_name']
obj.save()
return redirect('accounts:update_user')
context = {
'form': form
}
return render(request, 'accounts/update_user.html', context)
update_user.html:
<h1>Update User Profile</h1>
<hr>
<form method="POST" enctype="multipart/form-data"> {% csrf_token %}
{{form.as_p}}
<button type="submit" class="btn btn-primary">Update</button>
</form>
the problem:
when trying to update my account, if i don't wish to change my email (just my first name or lastname) it displays the error 'Custom user with this Email address already exists'
i have searched for many solutions and the only one that seemed to work is passing through the clean function on the update form as shown below:
forms.py
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
def clean(self):
pass
this fixes the issue and allows you to update your first or last name without updating your email.
However, this causes another bug.
when i try to change my email to a differnt email that already exists in my database instead of getting the 'Custom user with this Email address already exists' error, it loads this screen instead
error that is occuring with clean function fix in place
so the question is how do i stop the 'Custom user with this Email address already exists' error when im not updating my email but allow the error when i am changing my email and that email already exists.
Since you want to update the object you should simply pass the keyword argument instance to the form instead of passing initial. You get the error 'Custom user with this Email address already exists' because when you write CustomUserChangeForm(request.POST, request.FILES) and it tries to validate the form it considers this as creating a new user and this gives you an error.
From the documentation on The save() method of ModelForm:
A subclass of ModelForm can accept an existing model instance as
the keyword argument instance; if this is supplied, save()
will update that instance. If it’s not supplied, save() will
create a new instance of the specified model
So your view should be like:
def update_user_view(request):
obj = CustomUser.objects.get(email=request.user.email)
form = CustomUserChangeForm(instance=obj)
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, request.FILES, instance=obj)
if form.is_valid():
obj = form.save()
return redirect('accounts:update_user')
context = {
'form': form
}
return render(request, 'accounts/update_user.html', context)
Next change your form back so that the clean method is unchanged:
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
I'm working on a simple login and logout app in Django.
I wrote two views one for login and another for register.
Register view is working as expected. But login view is causing issues.
I'm using form.is_valid() in login view. That is where the issue is arising. If I print the form in else block, it is saying A user with that username already exists. This is happening even before trying to authenticate the user. Some one help me with this.
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.http.response import HttpResponse
from django.shortcuts import render
from notes.forms import UserForm
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user:
login(request, user)
return HttpResponse("Logged in")
else:
return HttpResponse("Wrong creds")
else:
print(form)
return HttpResponse("else of is_valid()")
def register(request):
if request.method == 'GET':
return render(request, 'register.html')
elif request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
email = form.cleaned_data['email']
existing = User.objects.filter(username=username)
if existing:
return HttpResponse('Username is already taken')
else:
User.objects.create(username=username, password = password, email=email)
return HttpResponse("User created with "+ username +" username")
else:
return HttpResponse("Hi")
forms.py
from django.contrib.auth.models import User
from notes.models import Note
from django import forms
class NoteForm(forms.ModelForm):
class Meta:
model = Note
fields = '__all__'
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'email', 'password']
The form.is_valid() call will validate the form, this is done through several steps. Depending on the fields of the model, it thus also checks the uniqness of the data.
The User [Django-doc] model has a uniqness constraint on the username, hence the UserForm can only be valid, if the username is not yet taken, or when the form contains a instance that is already stored in the database.
I therefore think that it might be better to create a LoginForm, like Django does with an AuthenticationForm [Django-doc] [GitHub]. For example:
class UserForm(forms.Form):
username = forms.CharField()
password = forms.CharField()
In a django project i'm working on I wrote a function to validate the data from a login form. Now whenever I run the is_valid() method on a instance of the login form it returns false everytime. I've been trying to figure out what's causing this problem all day.
forms.py:
from django import forms
from django.contrib.auth import authenticate, password_validation
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User, Group
from .functions import *
from .models import *
class login_form(forms.Form):
username = forms.CharField(max_length=64, label='Username', widget=forms.TextInput(attrs={'placeholder': 'username...', 'class':'login-field'}))
password = forms.CharField(max_length=24, label='Password', widget=forms.PasswordInput(attrs={'placeholder': 'password...', 'class':'login-field'}))
def clean(self, *args, **kwargs):
username = self.cleaned_data.get('username', None)
password = self.cleaned_data.get('password', None)
user_obj = None
self._errors['username'] = None #clears default username error
self._errors['password'] = None #clears default password error
if username is not None:
try:
user_obj = User.objects.get(username=username)
if password_validation.validate_password(password, user_obj) is None:
self._errors['password'] = 'Password is incorrect. Please try again.'
except User.DoesNotExist:
self._errors['username'] = 'User does not exist. Please use valid credentials.'
else:
self._errors['username'] = 'Please type a valid username.'
return super(login_form, self).clean(*args, **kwargs)
views.py:
from django.shortcuts import render, redirect
from django.http import HttpRequest, JsonResponse, HttpResponse
from django.template import RequestContext
from django.conf.urls import patterns
from django.contrib import admin
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User, Group
from datetime import datetime
from .models import *
from .forms import *
from .functions import *
from os import *
import shutil
import json
def home(request):
if request.method == 'POST':
form = login_form(request.POST)
if form.is_valid():
username = form.data.get('username')
password = form.data.get('password')
authenticate_usr_obj = authenticate(username=username, password=password)
if authenticate_usr_obj is not None:
login(request, authenticate_usr_obj)
return redirect(dashboard)
else:
form = login_form()
try:
logout_successful = request.session.get('logout_complete', False)
request.session['logout_complete'] = False
except:
logout_successsful = False
context = {
'body_class': 'login',
'login': form,
'logout_successful': logout_successful
}
return render(request, 'development/index.html', context)
Just by reading throught Forms API docs I can see that in your example you did not clean data before you tried to get them in lines:
username = self.cleaned_data.get('username', None)
password = self.cleaned_data.get('password', None)
try to first use clean() to validate the data, like this:
cleaned_data = super(login_form, self).clean()
Then you can try to get them like this:
username = cleaned_data.get('username', None)
password = cleaned_data.get('password', None)
You can find more here
Version 2:
Ok, so first of all what I found in Django docs regarding the django.contrib.auth.password_validation.validate_password():
Integrating validation
validate_password(password, user=None, password_validators=None)
Validates a password. If all validators find the password valid, returns None. If one or more validators reject the password, raises a ValidationError with all the error messages from the validators.
The user object is optional: if it’s not provided, some validators may not be able to perform any validation and will accept any password.
So the line:
if password_validation.validate_password(password, user_obj) is None:
should be:
if password_validation.validate_password(password, user_obj) is not None:
Second of all:
Form.errors
>>>> f.errors
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}`
In this dictionary, the keys are the field names, and the values are lists of Unicode strings representing the error messages. The error messages are stored in lists because a field can have multiple error messages.
So based on that, I would change lines where you define your custom messages to look more something like this:
self.errors['password'] = [u'Password is incorrect. Please try again.']
And the one last thing to remember is that clean method must return the cleaned_data.
Final version of forms.py code could look something like that:
def clean(self):
super(login_form,self).clean()
username = self.cleaned_data.get('username', None)
password = self.cleaned_data.get('password', None)
if username is not None:
try:
user_obj = User.objects.get(username=username)
if password_validation.validate_password(password, user_obj) is not None:
self.errors['password'] = [u'Password is incorrect. Please try again.']
except User.DoesNotExist:
self.errors['username'] = [u'User does not exist. Please use valid credentials.']
else:
self.errors['username'] = [u'Please type a valid username.']
return self.cleaned_data
Hopefully it helps this time.
Tested your code above and I've encountered error due to forms self._errors
`Nonetype` object is not iterable
And here is my suggestion
forms.py
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
class login_form(forms.Form):
username = forms.CharField(
max_length=64, label='Username',
widget=forms.TextInput(
attrs={'placeholder': 'username...', 'class': 'login-field'}))
password = forms.CharField(
max_length=24, label='Password',
widget=forms.PasswordInput(
attrs={'placeholder': 'password...', 'class': 'login-field'}))
def clean_username(self):
data = self.cleaned_data.get('username', None)
if not data:
raise ValidationError('Please type a valid username.',
code='invalid')
return data
def clean(self, *args, **kwargs):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
try:
user_obj = User.objects.get(username=username)
if not user_obj.check_password(password):
raise ValidationError(
'Password is incorrect. Please try again',
code='incorrect')
except User.DoesNotExist:
raise ValidationError(
'User does not exist. Please use valid credentials.',
code='invalid')
return super(login_form, self).clean(*args, **kwargs)
views.py
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth import logout
from .forms import *
def home(request):
logout_successful = True
if request.method == 'POST':
form = login_form(request.POST)
# print form.errors
if form.is_valid():
username = form.data.get('username')
password = form.data.get('password')
authenticate_usr_obj = authenticate(
username=username, password=password)
if authenticate_usr_obj:
login(request, authenticate_usr_obj)
# print 'ok'
else:
form = login_form()
logout_successful = request.user.is_authenticated()
return render(request, 'base.html', {
'body_class': 'login',
'login': form,
'logout_successful': logout_successful
})
def logout_view(request):
logout(request)
I'm still a beginner so feel free to comment something
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