How to prevent 'no username' in django? - django

This is what my registration form looks like:
I want to make it so that if the user doesn't write anything in the given text boxes, a warning sign pops up and say that ' a username must be inputted' or something like that
but when i click the submit button, Value error occurs, saying that "The given username must be set"
def register(request):
context = {
'error_message': None,
}
if request.method == 'POST':
username = request.POST['username']
password1 = request.POST['password1']
password2 = request.POST['password2']
email = request.POST['email']
if password1==password2:
if User.objects.filter(username=username).exists() or Person.objects.filter(username=username).exists():
context['error_message'] = '이미 사용중인 아이디입니다.'
return render(request, 'UserAdministration/register.html', context)
elif User.objects.filter(email=email).exists() or Person.objects.filter(username=username).exists():
context['error_message'] = '이미 사용중인 이메일입니다.'
return render(request, 'UserAdministration/register.html ', context)
else:
user = User.objects.create_user(
password=password1,
email=email,
username=username
)
user.save()
masked_username = generate_masked_username.generate_masked_username(username)
person = Person.objects.create(
username=username,
masked_username=masked_username,
email=email,
password=password1
)
person.save()
return redirect('login')
else:
context['error_message'] = '비밀번호가 맞지 않습니다.'
return render(request, 'UserAdministration/register.html', context)
# return redirect('/')
# originally was homepage.html. Doesn't know if this changed anything. just a note
else:
return render(request, 'UserAdministration/register.html', context)
This is my code... anybody know how to prevent this error?

This is what forms are for. You should use a Form (or ModelForm) rather than building the form and using request.POST manually. Then you will get better errors. These docs will be especially useful.
A quick example:
Form:
from django import forms
from django.contrib.auth import get_user_model
class RegistrationForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ["username", "email", "password"]
View:
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
from .forms import RegistrationForm
class UserRegistrationView(CreateView):
form_class = RegistrationForm
template_name = "registration/register.html"
success_url = reverse_lazy("login")
This will get you most of the way there, you just need to add a custom field and some logic for the password2 validation and handle whatever the masked username stuff is.
Registration is such a common workflow however, that you can also use a package like django-registration to handle the details for you, and you can just override what you need for your custom logic where it's needed.

Related

Advice on Django user profile edit views

I'm building a Django app that will have users and profile models associated with them and they should have the ability to edit their profile in a view. As I see there are two similar but slightly different approaches how that could be done.
An UpdateView could be used that retrieves a pk from the url and then verifies if the pk corresponds to the actual authenticated user, for instance:
class ProfileUpdateView(UpdateView):
model = Profile
fields = ['field1', 'field2']
def get_object(self, queryset=None):
obj = super().get_object(queryset=queryset)
if obj.user != self.request.user:
# If the object user does not match the logged in user,
# raise a 404 Not Found exception.
raise Http404("You do not have permission to edit this profile.")
return obj
Or an alternative way that would check/ reference the current user via Django's authentication backend, for instance:
def profile_update(request):
profile = request.user.profile
form = ProfileForm(request.POST or None, instance=profile)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'profile_update.html', context)
The main question is a bit generic, hence the name 'advice' in the post title, but are there any benefits/ risks associated with one or the other way of implementing a profile edit view that one should definitely consider when choosing between the two? The relationship between User and Profile model is a OneToOne relationship.
Thank's
I would not say it makes any difference, as long as only authenticated user can login in and one user can not modify other's profile. You can take any of the approaches, even implement the second approach in the first view (using /update/profile within Class Based View), like this:
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
model = Profile
fields = ['field1', 'field2']
def get_object(self, queryset=None):
return self.request.user.profile
But you need to use LoginRequiredMixin with the view so that only authenticated users can log in.
A simpler way is to use the framework's own functions directly, for example, use login_required to check if a user is logged in, and forms to control user profile editing.
Here is my own code for your reference.
views.py
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import UserProfileForm
#login_required
def userinfo(request):
if request.method == 'POST':
form = UserProfileForm(request.POST)
if form.is_valid():
user = User.objects.get(pk=request.user.id)
user.first_name = form.cleaned_data['fullname']
user.email = form.cleaned_data['email']
user.save()
msg = "Profile updated!"
messages.add_message(request, messages.SUCCESS, msg)
return redirect('user.info')
else:
form = UserProfileForm()
context = {
'title': 'My Profile',
'form': form,
}
return render(request, 'accounts/info.html', context)
forms.py
from django import forms
class UserProfileForm(forms.Form):
fullname = forms.CharField(
label="Name",
error_messages={
'required': 'Required!',
})
email = forms.EmailField(
label="E-mail",
error_messages={
'required': 'Required!',
'invalid': 'The format is not correct!',
})

How to validate data entered in the sign up form created in Django?

I have created a registration form using the class models.User (refer) in Django as follows:
from Django.shortcuts import render, redirect
from django.contrib.auth.models import User
def register(request):
if request.method == 'POST':
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
confirm_password = request.POST['confirm_password']
if password == confirm_password:
# some code
user = User.objects.create_user(username=username, email=email, password=password)
user.save()
return redirect('login')
else:
return redirect('register')
return render(request, 'register.html')
My problems:
Now I want to make Full Name as optional but all other fields as required, also I want to apply length constraint on my fields, how can I do that? As this is an inbuilt model (class models.User), I am not sure how to set blank=True or use max_length for any field.
Also I want to remove the spaces (if any) at the end and beginning of the entered data, before saving it using user.save() (e.g. if someone entered the name as " abc efg " I want to save it as "abc efg"). Basically, I want to use .is_valid() feature of the Django forms. I even tried doing that as:
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
def register(request):
if request.method == 'POST':
form = User(request.POST or None)
if form.is_valid():
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
confirm_password = request.POST['confirm_password']
if password == confirm_password:
# some code
user = User.objects.create_user(username=username, email=email, password=password)
user.save()
return redirect('login')
else:
return redirect('register')
else:
return redirect('register')
return render(request, 'register.html')
but this is giving me the following error: 'User' object has no attribute 'is_valid'
Any ideas about how can I make the fields optional/required and set the max_length of the fields & remove the trailing spaces (if any) all while using the inbuilt model class models.User?
You need to declare a form first. If you are using default django user, then you can user UserCreationForm to validate the data:
from django.contrib.auth.forms import UserCreationForm
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST or None)
if form.is_valid():
form.save()
# rest of the code
Now, lets say you want want to clean the data which you get from the HTML form, then you can use clean_<field_name> method. To do that inside UserCreationForm, you can override it(also adding some code to show how to customize forms):
class CustomUserForm(UserCreationForm):
first_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
def clean_first_name(self):
return self.cleaned_data['first_name'].strip()
Please see the documentation for more information on validation and cleaning data in forms.
As per the django docs, it is best to create your own user model by inheriting from the AbstractBaseUser: https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#specifying-a-custom-user-model
There you can define what's optional and what not.
Oh, and while you're at it - maybe it's also worth looking at django-allauth. Maybe not too relevant right now but for sure down the road! Also check out the custom forms.

How do I login with with the user credentials in Django?

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()

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

Issues with auth_user table

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