Django form meta and validation - django

I have form:
class FindAdvert(forms.ModelForm):
class Meta:
model = Advert
fields = ('id', 'code')
But in this way I can't 'login' because validation return error: id already exist.
How modify this form to allow 'login' (instead of registration)?

You don't need ModelForm for login, because it's semantical goal - create|edit database data (anyway you can hardcode id in your view - but it is wrong way).
So create simple Form with custom validation rules (in clean method or in your views), something like that below:
class LoginForm(forms.Form):
username = forms.CharField(
label=u'Username',
required=True,
)
password = forms.CharField(
label=u'Password',
required=True,
widget=forms.PasswordInput
)
def clean(self):
cleaned_data = super(LoginForm, self).clean()
username = cleaned_data.get('username')
password = cleaned_data.get('password')
if (username and password and User.objects.filter(username=username).count() == 0)\
or (username and password and User.objects.filter(username=username).count() == 1 and
User.objects.get(username=username).password != password):
raise forms.ValidationError(u'Wrong username or password')
return cleaned_data
views:
from django.contrib.auth import logout, authenticate, login
from django.views.generic import FormView, RedirectView
# ...
class LoginFormView(FormView):
template_name = 'common/login.html'
form_class = LoginForm
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
logout(request)
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_superuser:
login(request, user)
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
return self.request.GET.get('next') or reverse('human:add')
class LogoutRedirectView(RedirectView):
permanent = False
def get_redirect_url(self, *args, **kwargs):
logout(self.request)
return reverse('common:login')

Related

Django Form not saving for Custom User Model

I have a register user form which is doing all the validation as expected. However, it is not saving. I am not able to figure out the reason. How do I debug it ? Any help ? I am a newbie to forms and formviews any good document with example would really help me.
class RegisterForm(forms.ModelForm):
phone_number = forms.IntegerField(required=True)
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())
country_code = forms.IntegerField()
#schools = school.objects.all()
#school_name = forms.ModelChoiceField(queryset=school.objects.distinct())
MIN_LENGTH = 4
class Meta:
model = User
fields = ['username','country_code','phone_number', 'password1', 'password2',
'full_name' ]
def clean_phone_number(self):
phone_number = self.data.get('phone_number')
print(phone_number)
if User.objects.filter(phone_number=phone_number).exists():
raise forms.ValidationError(
_("Another user with this phone number already exists"))
if len(phone_number) == 10 and phone_number.isdigit():
pass
else:
raise forms.ValidationError(
_("Invalid Phone Number"))
return phone_number
def save(self, *args, **kwargs):
print("saving")
user = super(RegisterForm, self).save(*args, **kwargs)
user.set_password(self.cleaned_data['password1'])
print('Saving user with country_code', user.country_code)
user.save()
return user
Views.py
class RegisterView(SuccessMessageMixin, FormView):
template_name = 'register-2.html'
form_class = RegisterForm
success_message = "One-Time password sent to your registered mobile number.\
The verification code is valid for 10 minutes."
def form_valid(self, form):
full_name=self.request.POST["full_name"]
user = form.save()
print(user.id)
username = self.request.POST['username']
password = self.request.POST['password1']
user = authenticate(username=username, password=password)
kwargs = {'user': user}
self.request.method = 'POST'
print("User created")
The print in clean_phone_number works however, save does not work
I had issue in the my form. One of the field was disabled and the value was not captured because of that.
However to identify that I used
def form_invalid(self,form):
# Add action to invalid form phase
messages.error(self.request, form.errors)
return self.render_to_response(self.get_context_data(form=form))

Django Authenticate Backends with Email

I want to login with email not username like this, please help
class loginUser(View):
def get(self, request):
lF = loginForm
return render(request, 'UserMember/login.html', {'lF': lF})
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'UserMember/private.html')
else:
return HttpResponse('login fail')
First thing is to create a default email field.
# models.py
class CustomUser(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
# settings.py (remember to migrate)
AUTH_USER_MODEL = 'accounts.CustomUser' # new
Next, create your custom email backend:
# backends.py (in-app)
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = UserModel.objects.get(
Q(username__iexact=username) | Q(email__iexact=username))
except UserModel.DoesNotExist:
UserModel().set_password(password)
except MultipleObjectsReturned:
return User.objects.filter(email=username).order_by('id').first()
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
def get_user(self, user_id):
try:
user = UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
# settings.py (migrate again)
AUTH_USER_MODEL = 'accounts.CustomUser'
AUTHENTICATION_BACKENDS = ['accounts.backends.EmailBackend'] # new
If you plan on using Django's default register/login forms, do:
# form.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import get_user_model
from django import forms
class RegisterForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('email', 'username', 'password1', 'password2')
class LoginForm(AuthenticationForm):
username = forms.CharField(label='Email / Username')
And then it's only the views and URLs to handle.
Ref
you need to work with allAuth
Follow this Link
hope it will be helpful.

RelatedObjectDoesNotExist Error

Here is the model. I have created my own user model
class Profile(models.Model):
user = models.OneToOneField(User)
favorite_food = models.CharField(max_length=100)
def set_password(self, raw_password):
self.user.set_password(raw_password)
Here is the view:
class UserFormView(View):
form_class = UserForm
template_name = 'templates/core/profile_form.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return render(request, self.template_name, {'form': form})
Here is UserForm
class UserForm(forms.ModelForm):
username = forms.CharField(max_length=10)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = Profile
fields = ['username', 'password', 'favorite_food']
Where seems to be the problem here? It also says that Profile has no user I have tried changing it to AbstractUser however, it also displays about an error about reverse accessor
Try to exclude user from form and add save method to the form:
class ProfileForm(forms.ModelForm):
username = forms.CharField(max_length=10)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = Profile
fields = ['username', 'password', 'favorite_food']
exclude = ['user']
def save(self, user = None, force_insert=False, force_update=False, commit=False):
username = self.cleaned_data['username']
password = self.cleaned_data['password']
profile = super(ProfileForm, self).save(commit=commit)
if user:
profile.user = user
profile.set_password(password)
profile.save()
return profile
In you view:
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
profile = form.save(user = request.user, commit=False)

Username and password authentication in django

I need to validate username and password in django app, below are the details
view is,
class HomeView(TemplateView):
template_name = 'home.html'
template_name2 = 'Logout.html'
def get(self,request):
form = LoginForm()
posts=users_data.objects.all()
args = {'form': form, 'posts': posts}
return render(request, self.template_name, args)
return render(request,self.template_name, {'form':form})
#template_name2 = 'Welcome.html'
def post(self,request):
form = LoginForm(request.POST)
if form.is_valid():
#text=form.cleaned_data['post']
username = forms.cleaned_data.get("Username")
password = forms.cleaned_data.get("Password")
user = authenticate(username=username, password=password)
if not user:
raise forms.ValidationError("This user does not exist")
return render(request, self.template_name1)
else:
form.save()
return render(request, self.template_name2)
else:
return render(request, self.template_name1)
after entering username and password it is giving me error and doing nothing. I am stuck at this point . Requesting for help.
my form is,
from django import forms
from login.models import *
from django.contrib.auth import authenticate,login,logout,get_user_model
user=get_user_model()
class SignupForm(forms.ModelForm):
class Meta:
model=users_data
fields=('Name','Email','Username','Password')
class LoginForm(forms.ModelForm):
class Meta:
model=users_data
fields=('Username','Password')
def clean(self):
username = self.cleaned_data.get("Username")
password = self.cleaned_data.get("Password")
user=authenticate(username=username,password=password)
if not user:
raise forms.ValidationError("This user does not exist")
You can use get user input from LoginForm this code blog.
username = form.cleaned_data.get("Username")
password = form.cleaned_data.get("Password")

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