django sign up form not storing the username - python

I have a sign up form that does not store the username properly, other fields are stored successfully. Shouldn't it save the username because it is in the fields ? I saw that I cannot login and this is because the row in the table does not have the username.
views.py
class SignUpFormView(FormView):
form_class = SignUpForm
template_name = 'users/authentication/login/signup.html'
def post(self, request):
form = self.form_class(data=request.POST)
if form.is_valid():
user = form.save(commit=False)
# some logic here
user.save()
messages.success(
request, "Great! You are able to login now.")
return redirect('login')
else:
messages.error(request, form.errors)
return redirect('login')
forms.py
class CustomUserCreationForm(UserCreationForm):
def clean_username(self):
username = self.cleaned_data["username"]
try:
TbUser.objects.get(username=username)
except TbUser.DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
class Meta(UserCreationForm.Meta):
model = TbUser
class SignUpForm(CustomUserCreationForm):
email = forms.EmailField()
customer_id = forms.CharField(label="Customer ID")
def clean_username(self):
data = self.cleaned_data['username']
if TbUser.objects.filter(username=data).exists():
raise forms.ValidationError(
"Username already exists. Pick another one")
def clean(self):
cd = self.cleaned_data
password1 = cd.get("password1")
password2 = cd.get("password2")
if password1 != password2:
raise ValidationError("Passwords did not match")
return cd
class Meta:
model = TbUser
fields = ['username', 'email', 'real_name', 'customer_id',
'password1', 'password2']

The clean_username method of SignUpForm does not return anything. You need to return cleaned data for it. So add return data to the bottom of this method.

Related

Django - How to create a user-owned group when registering?

I'm using Django. User registration form contains fields such as username, e-mail, password. I want the user to create their own group when registering. How do I add this field?
forms.py
class RegisterForm(forms.ModelForm):
username = forms.CharField(max_length=100, label='Kullanıcı Adı')
email = forms.EmailField(max_length=200, help_text='Required')
password1 = forms.CharField(max_length=100, label='Parola', widget=forms.PasswordInput)
password2 = forms.CharField(max_length=100, label='Parola Doğrulama', widget=forms.PasswordInput)
class Meta:
model = User
fields = [
'username',
'email',
'password1',
'password2',
]
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Parolalar eşleşmiyor!")
return password2
def clean_email(self):
email = self.cleaned_data.get('email')
lenghtw = len(User.objects.filter(email=email))
if lenghtw > 0 :
raise forms.ValidationError('Bu email adresine sahip bir kullanıcı zaten var.')
return email
views.py
def register_view(request):
form = RegisterForm(request.POST or None)
if form.is_valid():
user = form.save(commit=False)
password = form.cleaned_data.get('password1')
user.set_password(password)
#user.is_staff = user.is_superuser = True
user.save()
new_user = authenticate(username=user.username, password=password)
login(request, new_user)
return redirect('home')
return render(request, 'accounts/form.html', {'form': form, 'title': 'Üye Ol'})
The screenshot OP gave as a comment is more explicit than his/her question, which should be edited :-)
As a summary:
thanks to a view + form, you want to create a new user and a new group (Grup Name field),
when your user is created, you want your user to automatically belong to your new group.
A few issues I see in your approach:
you are coding a form which already exists in Django (UserCreationForm from django.contrib.auth.forms), with unnecessary checks (as for password validation: it has already been done by Django),
your field Grup name is not in your form by the way, did you forget it?
your user needs to be saved to database already, so it can have a pk and be added to a group.
We could also use signals to do so, but let's go with your own approach:
# forms.py
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
new_group_name = forms.CharField(max_length=100, label='Grup Name')
def clean_new_group_name(self):
# if you need to check the name of the group name
[...]
# views.py
def register_view(request):
form = RegisterForm(request.POST or None)
if form.is_valid():
user = form.save() # <--- ! don't use commit=False here
password = form.cleaned_data.get('password1')
new_group_name = form.cleaned_data['new_group_name']
new_group, created = Group.objects.update_or_create(name=new_group_name)
user.groups.add(Group.objects.get(name=new_group_name)
user.save()
new_user = authenticate(username=user.username, password=password)
login(request, new_user)
return redirect('home')
return render(request, 'accounts/form.html', {'form': form, 'title': 'Üye Ol'}
Could you try if that works for you?

How do I control what authenticated users can see in Django?

Trying to hide a view to create a restaurant from anyone other than a restaurant Owner.
Used examples shown using groups and testing whether a user is in that group or not but nothing seems to work.
views.py
def is_owner(user):
if user.objects.filter(name="Owner").exists():
return True
class CreateRestaurantView(generic.CreateView):
form_class = CreateRestaurantForm
success_url = reverse_lazy('home')
template_name = 'signup.html'
#login_required
def create_restaurant(request):
if is_owner == True:
if request.method == "POST":
form = CreateRestaurantForm(request.POST)
if form.is_valid():
restaurant = form.save(commit=False)
restaurant.Restaurant_Owner = request.user
restaurant.save()
return redirect('restaurant_list')
else:
form = CreateRestaurantForm()
return render(request, 'create_restaurant.html', {'form': form})
else:
return render(request, 'home.html')
forms.py
signup form for Owners
class OwnerCreationForm(forms.ModelForm):
error_messages = {
'password_mismatch': _("The two password fields didn't match."),
}
password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput,
help_text=_("Enter the same password as above, for verification."))
class Meta:
model = User
fields = ("username",)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def save(self, commit=True):
user = super(OwnerCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
group = Group.objects.get(name='Owner')
user.groups.add(group)
return user
I'm trying to get the view to show the create_restaurant form when a user belongs to the "Owner" group but the function to test (is_owner) does not work and is always false.
First of all, you are defined is_owner as function, so, you should call it as is_owner(any_user_object)
Second thing is, to search over the Group, it should be as
user.groups.filter(name="Owner").exists()
code snippet
def is_owner(user):
return user.groups.filter(name="Owner").exists()
#login_required
def create_restaurant(request):
if is_owner(request.user) == True:
if request.method == "POST":
form = CreateRestaurantForm(request.POST)
if form.is_valid():
restaurant = form.save(commit=False)
restaurant.Restaurant_Owner = request.user
restaurant.save()
return redirect('restaurant_list')
else:
form = CreateRestaurantForm()
return render(request, 'create_restaurant.html', {'form': form})
else:
return render(request, 'home.html')
UPDATE-1
change the save() method of OwnerCreationForm as below
class OwnerCreationForm(forms.ModelForm):
# your other code
def save(self, commit=True):
user = super(OwnerCreationForm, self).save(commit=True)
user.set_password(self.cleaned_data["password1"])
if not user.groups.filter(name="Owner").exists():
group = Group.objects.get(name='Owner')
user.groups.add(group)
user.save()
return user

django2.0 forms.ValidationError always return me 'password_mismatch'!

I want to valid email isn't exists, so I do this
forms.py
class RegisterForm(auth_forms.UserCreationForm):
code = forms.CharField(label=_('valid code'), max_length=6)
def clean(self):
cleaned_data = super().clean()
email = cleaned_data['email']
if email and User.objects.filter(email=email):
raise forms.ValidationError(_('email already in use'), code='invalid')
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', 'code')
and I want, when user register, if email is exists, I will return "email already in user" to him, now I just print it, when forms is invalid, so I do this in views.py
views.py
class RegisterView(SuccessMessageMixin, FormView):
template_name = 'account/signup.html'
form_class = RegisterForm
extra_context = {'page': 'register'}
success_url = '/'
success_message = _('register success')
def form_valid(self, form):
user = form.save()
login(self.request, user)
return super().form_invalid(form)
def form_invalid(self, form):
print(form.error_messages)
error_msg = list(form.error_messages.values())[0]
return utils.ajax_error(error_msg)
but, when I run it, I give some data to form, is all valid exists email
I should get email aliready in use, but I always get {'password_mismatch': "The two password fields didn't match."}
but the password1 and password2 is same!
Why I always get the error about password !

How to allow user to change his attributes?

I'm trying to figure out how to allow users to change their profile. I have a Users extended by User Profile (OneToOne).
I was thinking about changing registration view, prefill user's attributes and allow him to change them. But it is not probably the good way.
Could you give me a hint how to do that?
class UserForm(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password1','password2', 'first_name', 'last_name')
def clean(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return self.cleaned_data
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('telephone','marital_status','how_do_you_know_about_us')
MODELS.PY
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
# ATRIBUTY KTORE BUDE MAT KAZDY
telephone = models.CharField(max_length=40,null=True)
HOW_DO_YOU_KNOW_ABOUT_US_CHOICES = (
('coincidence',u'It was coincidence'),
('relative_or_friends','From my relatives or friends'),
)
how_do_you_know_about_us = models.CharField(max_length=40, choices=HOW_DO_YOU_KNOW_ABOUT_US_CHOICES, null=True)
MARITAL_STATUS_CHOICES = (
('single','Single'),
('married','Married'),
('separated','Separated'),
('divorced','Divorced'),
('widowed','Widowed'),
)
marital_status = models.CharField(max_length=40, choices=MARITAL_STATUS_CHOICES, null=True)
# OD KIAL STE SA O NAS DOZVEDELI
# A STAV
def __unicode__(self):
return '{} {}'.format(self.user.first_name,self.user.last_name)
def __str__(self):
return '{} {}'.format(self.user.first_name,self.user.last_name)
REGISTRATION VIEW:
def register(request):
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = UserProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user_form.cleaned_data['password1'])
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
return register_success(request)
else:
print user_form.errors, profile_form.errors
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request, "auth/registration/register.html",
context={'user_form': user_form, 'profile_form': profile_form})
EDIT:
This is the view I'm trying to create but it does not autofill form:
#login_required
def edit_profile(request):
myUser = request.user
user_form = UserForm(request.POST, instance=myUser)
user_profile_form = UserProfileForm(request.POST, instance=myUser)
context={'user_form': user_form,
'user_profile_form':user_profile_form}
return render(request, 'auth/profiles/my_profile.html', context=context)
In the edit_profile view you added, you're passing your forms a POST request argument. You should only be passing this argument on a POST request. So update your forms to be the following if the request is a GET request:
views.py
user_form = UserForm(instance=myUser)
user_profile_form = UserProfileForm(instance=myUser)
forms.py
# Something like this will only save password if data is entered in one of the password fields
def clean(self):
cleaned_data = super(UserForm, self).clean()
password1 = cleaned_data.get('password1', None)
password2 = cleaned_data.get('password2', None)
old_password = cleaned_data.get('old_password', None)
if password1 or password2:
if password1 != password2:
self._errors['password1'] = 'New Password and Confirm New Password must match.'
self._errors['password2'] = 'New Password and Confirm New Password must match.'
if not self.user.check_password(old_password):
self._errors['old_password'] = 'Your old password was entered incorrectly.'
return cleaned_data
def save(self, request):
user = self.user
if self.cleaned_data.get('password1', None):
user.set_password(self.cleaned_data.get('password1'))
update_session_auth_hash(request, user)
user.save()
return user
For your choices issue, you can specify choices as an argument when specifying widgets for the field.

How to exclude fields from form prefilled with object

How to exclude some fields from form created in view from instance?
I want to allow users to edit their attributes like username or telephone but in this form, they shouldn't change their password.
I've tried this:
del user_profile_form.fields['telephone']
But it raises CSRF token missing or incorrect. when I do that.
#login_required
def edit_profile(request):
user = request.user
user_form = UserForm(instance=user)
user_profile_form = UserProfileForm(instance=user.userprofile)
context = {'user_form': user_form,
'user_profile_form': user_profile_form}
return render(request, 'auth/profiles/edit-profile.html', context=context)
FORMS.PY
class UserForm(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password1','password2', 'first_name', 'last_name')
def clean(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return self.cleaned_data
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('telephone','marital_status','how_do_you_know_about_us')
MODELS.PY
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='userprofile')
# ATRIBUTY KTORE BUDE MAT KAZDY
telephone = models.CharField(max_length=40,null=True)
HOW_DO_YOU_KNOW_ABOUT_US_CHOICES = (
('coincidence',u'It was coincidence'),
('relative_or_friends','From my relatives or friends'),
)
how_do_you_know_about_us = models.CharField(max_length=40, choices=HOW_DO_YOU_KNOW_ABOUT_US_CHOICES, null=True)
MARITAL_STATUS_CHOICES = (
('single','Single'),
('married','Married'),
('separated','Separated'),
('divorced','Divorced'),
('widowed','Widowed'),
)
marital_status = models.CharField(max_length=40, choices=MARITAL_STATUS_CHOICES, null=True)
# OD KIAL STE SA O NAS DOZVEDELI
# A STAV
def __unicode__(self):
return '{} {}'.format(self.user.first_name,self.user.last_name)
def __str__(self):
return '{} {}'.format(self.user.first_name,self.user.last_name)
NEW VIEW
#login_required
def edit_profile(request):
user = request.user
if request.method == 'POST':
user_form = UserForm(request.POST)
user_profile_form = UserProfileForm(request)
if user_form.is_valid() and user_profile_form.is_valid():
user_form.save()
user_profile_form.save()
return HttpResponseRedirect('/logged-in')
else:
print user_form.errors
print user_profile_form.errors
else:
user_form = UserForm(instance=user)
user_profile_form = UserProfileForm(instance=user.userprofile)
temp_user_profile_form = deepcopy(user_profile_form)
del temp_user_profile_form.fields['password1']
del temp_user_profile_form.fields['password2']
context = {'user_form': user_form,
'user_profile_form': temp_user_profile_form}
return render(request, 'auth/profiles/edit-profile.html', context=context)
ERROR
Exception Type: KeyError
Exception Value:
'password1'
It looks like you're referencing password1 and password2 in your Meta class for the UserForm model form. These should be removed, as they aren't fields in your User model. So after the change, your UserForm should be:
class UserForm(forms.ModelForm):
# These 2 fields are unbound fields...
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
# These fields are your User model's fields
fields = ('username', 'email', 'first_name', 'last_name')
def clean(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return self.cleaned_data
You don't need to remove them in the view. Just exclude them in the template.
Additionally, you can make the form fields hidden inputs in the __init__ method for your form if you'd like. I'd recommend this approach.

Categories

Resources