Django edit profile issues - django

The ability for a user to edit their profile using Django Userena all of a sudden doesnt work. It just returns to the same edit page without doing anything. Can anyone see whats wrong with the code. Thanks
forms.py
class EditProfileForm(forms.ModelForm):
""" Base form used for fields that are always required """
first_name = forms.CharField(label=_(u'First name'),
max_length=30,
required=False)
last_name = forms.CharField(label=_(u'Last name'),
max_length=30,
required=False)
def __init__(self, *args, **kw):
super(EditProfileForm, self).__init__(*args, **kw)
# Put the first and last name at the top
new_order = self.fields.keyOrder[:-2]
new_order.insert(0, 'first_name')
new_order.insert(1, 'last_name')
self.fields.keyOrder = new_order
class Meta:
model = get_profile_model()
exclude = ['user']
def save(self, force_insert=False, force_update=False, commit=True):
profile = super(EditProfileForm, self).save(commit=commit)
# Save first and last name
user = profile.user
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
return profile
views.py
enter code heredef profile_edit(request, username, edit_profile_form=EditProfileForm,
template_name='userena/profile_form.html', success_url=None,
extra_context=None, **kwargs):
"""
Edit profile.
Edits a profile selected by the supplied username. First checks
permissions if the user is allowed to edit this profile, if denied will
show a 404. When the profile is successfully edited will redirect to
``success_url``.
:param username:
Username of the user which profile should be edited.
:param edit_profile_form:
Form that is used to edit the profile. The :func:`EditProfileForm.save`
method of this form will be called when the form
:func:`EditProfileForm.is_valid`. Defaults to :class:`EditProfileForm`
from userena.
:param template_name:
String of the template that is used to render this view. Defaults to
``userena/edit_profile_form.html``.
:param success_url:
Named URL which will be passed on to a django ``reverse`` function after
the form is successfully saved. Defaults to the ``userena_detail`` url.
:param extra_context:
Dictionary containing variables that are passed on to the
``template_name`` template. ``form`` key will always be the form used
to edit the profile, and the ``profile`` key is always the edited
profile.
**Context**
``form``
Form that is used to alter the profile.
``profile``
Instance of the ``Profile`` that is edited.
"""
user = get_object_or_404(get_user_model(),
username__iexact=username)
profile = user.get_profile()
user_initial = {'first_name': user.first_name,
'last_name': user.last_name}
form = edit_profile_form(instance=profile, initial=user_initial)
if request.method == 'POST':
form = edit_profile_form(request.POST, request.FILES, instance=profile,
initial=user_initial)
if form.is_valid():
profile = form.save()
if userena_settings.USERENA_USE_MESSAGES:
messages.success(request, _('Your profile has been updated.'),
fail_silently=True)
if success_url: redirect_to = success_url
else: redirect_to = reverse('userena_profile_detail', kwargs={'username': username})
return redirect(redirect_to)
if not extra_context: extra_context = dict()
extra_context['form'] = form
extra_context['profile'] = profile
return ExtraContextTemplateView.as_view(template_name=template_name,
extra_context=extra_context)(request)

You have to run the following command to solve the problem
python manage.py check_permissions
i hope it will solve your problem.Cheers.

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

How to update django auth User using a custom form

I am using Django's built in authentication to manage users on a social media website. I am using a one-to-one relationship to attach a profile to each user. I can update all the parts of the profile I have attached using an UpdateView. However I don't know how to do that with Django's built in User. So I created a form that uses the _meta class. I have gotten to the point where my form will add a new user instead of update the current one. I was hoping one of you could help me fix my code. Thanks in advance for any help you can offer
views.py
class PrivProfileUpdate(View):
form_class = UserUpdateForm
template_name = 'user/user_form.html'
#display a blank form
def get(self, request, pk):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#proces form data
def post(self, request, pk):
form = self.form_class(request.POST)
user = User.objects.get(pk=pk)
if form.is_valid():
user = form.save(commit=True)
print("we are trying to save")
#cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
user.set_password(password) #this is the only way to change a password because of hashing
user.save()
return render(request, self.template_name,{'form': form})
forms.py
class UserUpdateForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password', 'first_name', 'last_name']
SOLUTION:
in views.py
class PrivProfileUpdate(UpdateView):
model = User
form_class = UserUpdateForm
template_name = 'user/user_form.html'
def form_valid(self, form):
user = form.save(commit=True)
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return redirect('user:index')
There's nothing special about the User class here. Just as with any other model, to update an existing instance you pass it as the instance argument to the form.
However, you do not actually need to do this at all yourself. You should be using an UpdateView, which does this for you; then you do not need to define get and post. The only method you need to define here is form_valid, to set the password:
class PrivProfileUpdate(UpdateView):
form_class = UserUpdateForm
template_name = 'user/user_form.html'
def form_valid(self, form):
user = form.save(commit=True)
password = form.cleaned_data['password']
user.set_password(password)
user.save()
return HttpResponseRedirect(self.get_success_url())

update password only if it is entered while updating user in Django admin

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

Validate nested form in Django

I have a UserProfile model which is linked OneToOne with Django User model. While adding a user through a form, I wanted to have one form for both of those. I found a snippet that does exactly that, and I didn't have any problem with it, until I wanted to validate the username. The form isn't throwing a ValidationError, like I would like it to, but returns an error page with ValueError: The User could not be created because the data didn't validate..
From what I understand (which obviously could be wrong), the current setup doesn't handle ValidationErrors from the nested form.
Is there any way to add that functionality? If not, how should I tackle the issue of having one form handle to models?
Code:
class CmUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(),
required=False,
help_text=_("Leave empty if you don't want "
"to change it"))
def clean_password(self):
data = self.cleaned_data['password']
if data.strip():
return make_password(data)
else:
# If password field is empty, then don't change it
return self.instance.password
def clean_username(self):
username = self.cleaned_data['username']
if get_user_model().objects.filter(username=username).exists():
raise forms.ValidationError(_('This username is already in use.'))
return username
class Meta:
model = get_user_model()
fields = ('first_name', 'last_name', 'email', 'username', 'password', 'is_staff', 'is_active')
class CmUserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# Take User if updating, None if creating
try:
self.user = kwargs['instance'].user
except AttributeError:
self.user = None
user_kwargs = kwargs.copy()
user_kwargs['instance'] = self.user
self.uf = CmUserForm(*args, **user_kwargs)
super(CmUserProfileForm, self).__init__(*args, **kwargs)
self.fields.update(self.uf.fields)
self.initial.update(self.uf.initial)
class Meta:
model = UserProfile
exclude = ['user']
def save(self, *args, **kwargs):
# Save User and pass it to UserProfile
user = self.uf.save(*args, **kwargs)
self.instance.user = user
return super().save(*args, **kwargs)
i implemented the same today. I learnt this from the this website tango with django. http://www.tangowithdjango.com/book/chapters/login.html. Also i provided my code how i achieved this. Inbuilt user model itself checks if the username already exists or not. hope this is helpful.
class Sam(models.Model):
user = model.OneToOneField(User)
#custom fields apart from the inbuilt User model
region = models.CharField(max_length=10)
designation = models.CharField(max_length=10)
#forms.py form models. Created SamProfileform to capture the custom fields which are specific to One's Profile and SamForm to capture the password and then hash later in the view.
#Please note that i didnt add any username check here. The inbuilt User does it for us. I verified it.
class SamForm(forms.ModelForm):
#form model to capture inbuilt fields of "User" model
password = forms.CharField(widget=PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password', 'firstname', 'lastname')
class SamProfileForm(forms.ModelForm):
#form model to built the custom fields in my case region and designation
class Meta:
model = Sam
fields = ('desgination', 'mgr')
def register(request):
registered = False
if request.method == 'POST':
user_form = SamForm(data=request.POST)
profile_form = SamProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
registered = True
else:
print user_form.errors, profile_form.errors
else:
user_form = SamForm()
profile_form = SamProfileForm()
template = loader.get_template('sam/register.html')
context = RequestContext(request, {
'user_form' : user_form, 'profile_form' : profile_form, 'registered' : registered,
})
return HttpResponse(template.render(context))

Django - The additional fields from UserProfile don't save

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,