User is Logged in and fills the form.
user enters the username in a form.
If the entered username doesn't match with username of logged in user raise error
forms.py
class iffc_one(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(iffc_one, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super().clean()
fieldentered_username = self.cleaned_data['current_user']
if self.user != fieldentered_username:
raise forms.ValidationError('Invalid user')
class Meta:
model = bookings_modelform
models.py
class bookings_modelform(models.Model):
current_user = models.CharField(max_length=200)
What am I doing wrong here!
You don't need to validate it, You just need get logged user information from request.user and put it into yourcmodel.
bookings_model.current_user = request.user.username
Related
I use a custom form inherited from django's UserCreationForm to add user. How ever i have to set different initial value for username field.It works perfectly but after hitting save button the user get saved with a different username than the initial value shown in the form.You can find the code below
from django.contrib.auth.forms import UserCreationForm
class AdminUserCreationForm(UserCreationForm):
"""
AdminForm for creating an instance of custom USER_MODEL.
"""
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("username", "email")
field_classes = {'username': UsernameField}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.initial['username'] = random_username_generator()
self.fields['username'].disabled = True
self.fields['password1'].required = False
self.fields['password2'].required = False
def clean_username(self):
username = self.cleaned_data['username'].lower()
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError('A user with username {} already exists'.format(username))
def clean_email(self):
email = self.cleaned_data['email'].lower()
try:
User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError('A user with email {} already exists'.format(email))
def save(self, commit=True):
import ipdb; ipdb.set_trace();
user = super(AdminUserCreationForm, self).save(commit=False)
# user = self.instance
qb = QuickBlox()
qb_password = reset_password_generator()
user.qb_password = qb_password + 'vx'
user.save()
attempt = LoginAttempts()
attempt.user = user
attempt.save()
send_invite_mail(user)
return user
I have SetPasswordForm that only sets user password
class SetPasswordForm(forms.Form):
password = forms.CharField(label="Password", widget=forms.PasswordInput)
def __init__(self, user, *args, **kwargs):
self.user = user
super(SetPasswordForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
self.user.set_password(self.cleaned_data['password'])
if commit:
self.user.save(update_fields=['password'])
return self.user
and User model that has activate() method to make new user activate after setting a password
class User(BaseUser):
activation_code = models.CharField(max_length=100, blank=True, null=True)
activated_at = models.DateTimeField(blank=True, null=True)
def activate(self):
self.is_active = True
self.activation_code = None
self.activated_at = datetime.now()
self.save(update_fields=['is_active', 'activation_code', 'activated_at'])
In view, when user submits a form, It should sets new password and activates user
class ActivateUserView(View):
def post(self, request, activation_code):
try:
user = User.objects.get(activation_code=activation_code)
except User.DoesNotExist:
return Http404()
form = SetPasswordForm(user=user, data=request.POST)
if form.is_valid():
user = form.save(commit=False)
user.activate()
return render(request, 'users/activate_user_done.html', {'user': user})
return render(request, self.template_name, {'user': user})
Question is I don't know where to call user.activate()?
In form or in view?
I don't think form.save() should also calls this method because form will not be reusable in other places.
Call user.activate before form.save because you only want to save the user if he has activated his account.
How to pass request to django form?
I am creating a django update profile form where user could change profile email. I want to check if email in form belongs to logged user if not then I want to check if this email is used by others users before setting it as new users email.
Here is my code and this self.request.user.email doesn't work:
def clean_email(self):
email = self.cleaned_data.get("email")
owns_email = (email != self.request.user.email)
if User.objects.filter(email__icontains=email).exists() and owns_email:
raise forms.ValidationError("This email aldready registered.")
return email
So maybe there is better solution to solve my problem?
Since you are using a cbv, you can use the get_form_kwargs function from the FormMixin.
It could look something like this:
class UserProfileUpdateView(UpdateView):
...
def get_form_kwargs(self):
'''This goes in the Update view'''
kwargs = super(UserProfileUpdateView, self).get_form_kwargs() #put your view name in the super
user = self.request.user
if user:
kwargs['user'] = user
return kwargs
Then your form class would look something like this, based on your above code:
class UserProfileUpdateForm:
...
def __init__(self, *args, **kwargs):
if kwargs.get('user'):
self.user = kwargs.pop('user', None)
super(UserProfileUpdateForm, self).__init__(*args,**kwargs)
def clean_email(self):
email = self.cleaned_data.get("email")
owns_email = (email != self.user.email)
if User.objects.filter(email__icontains=email).exists() and owns_email:
raise forms.ValidationError("This email already registered.")
return email
The form doesn't have the Request object. You need to manually pass the currently logged in user in the constructor. Your form should look something like this:
class UserProfileForm(forms.Form):
user = None
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(UserProfileForm, self).__init__(*args, **kwargs)
...
def clean_email(self):
email = self.cleaned_data['email']
owns_email = (email != self.user.email)
if User.objects.filter(email__icontains=email).exists() and owns_email:
raise forms.ValidationError('This email already registered.')
return email
...
Instantiating the form in the view:
def edit_profile(request):
form = UserProfileForm(user=request.user)
...
I have custom user in Django, so in user creation form in admin we have password field, and its getting saved while creation, but when I go to change existing user and I am not entering/changing password field , but it getting reflected in database. below is my code
class ChangeClientEmployeeMasterForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ChangeClientEmployeeMasterForm, self).__init__(*args, **kwargs)
self.fields['groups'].label='Roles'
if 'instance' in kwargs and hasattr(kwargs['instance'], 'client_employee_id'):
self.client_employee_id = kwargs['instance'].client_employee_id
def clean(self):
if self.cleaned_data['client_employee_type'] =='imast':
self.cleaned_data['is_superuser'] = True
else :
self.cleaned_data['is_superuser'] = False
return self.cleaned_data
def save(self, commit=True):
user = super(ChangeClientEmployeeMasterForm, self).save(commit=False)
password = self.cleaned_data["password"]
if password:
user.set_password(password)
if commit:
user.save()
return user
class Meta:
model = ClientEmployeeMaster
You try this option, I tried this in Django Admin 1.10. This should work.
def clean(self):
password = self.cleaned_data['password']
if not password and password =='':
del self.cleaned_data['password']
#Add your extra code / statement here, if you need.
return self.cleaned_data
I'm new with Django and Python... I'm trying to do my own registration form for add some additional fields (Following the docs about Profiles)... All fine when I test, but after save, the additional field don't save, without error, just don't save, only the User is created... but If I write manually some values on create_profile function, it's saved correct.. How I can pass fields from my UserCreateForms to create_profile routine?
Sorry for my english, and thanks for your help, I'm involved in a little project for learn and I'm stopped for this detail.. :S
Models
class UserProfile(models.Model):
user = models.OneToOneField(User)
cedula_de_identidad = models.CharField(max_length=9)
def create_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance, cedula_de_identidad='If I write here it's saved correctly')
post_save.connect(create_profile, sender=User)
Forms
class UserCreateForm(UserCreationForm):
email = forms.EmailField(required=True)
cedula_de_identidad = forms.CharField(required=True)
class Meta:
model = User
fields = ("email", "username", "password1", "password2")
def clean_username(self):
username = self.cleaned_data['username']
# if not re.search(r'^\w+$', username):
# raise forms.ValidationError('Username can contain only alphanumeric characters')
try:
User.objects.get(username=username)
except ObjectDoesNotExist:
return username
raise forms.ValidationError('Username is already taken')
def save(self, *args, **kwargs):
user = super(UserCreateForm, self).save(*args, **kwargs)
profile = UserProfile()
profile.user = user
profile.cedula_de_identidad = self.cleaned_data['cedula_de_identidad']
profile.save
return profile
Views
def nuevo_usuario(request):
if request.method == 'POST':
formulario = UserCreateForm(request.POST)
if formulario.is_valid():
formulario.save()
return HttpResponseRedirect('/')
else:
formulario = UserCreateForm()
return render_to_response('nuevousuario.html', {'formulario': formulario}, context_instance=RequestContext(request))
I'm using Python 2.7 and Django 1.4.. Regards,