问题
I'm working on a project using Python(3.7) and Django(2.2) in which I have implemented models for multiple types of users by extending the base User model. Now I need to implement a way to allow the admin user to edit a user ( can't use the default Django admin). So, I have utilized the MultiModelForm to combine multiple forms on a single template, on the get request the form is loading properly with data populated. Here's what I have done so far:
From models.py
:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=255)
title = models.CharField(max_length=255, choices=TITLE, blank=False)
user_type = models.CharField(max_length=255, choices=USER_TYPE, blank=False)
gender = models.CharField(max_length=255, choices=CHOICES, blank=False)
contenst = models.CharField(max_length=255, blank=True, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
email_status = models.CharField(max_length=50, default='nc')
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['password']
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
def __str__(self):
return str(self.email)
class ContactPerson(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
contact_email = models.EmailField(blank=False)
customer_id = models.BigIntegerField(blank=True)
contact_no = PhoneNumberField(blank=True, null=True, help_text='Phone number must be entered in the'
'format: \'+999999999\'. Up to 15 digits allowed.')
collection_use_personal_data = models.BooleanField(blank=False)
Here's the related forms.py
:
class EditUserForm(forms.ModelForm):
password = None
class Meta:
model = User
fields = ('email', 'name', 'title', 'gender', 'contenst',)
class UserCPForm(forms.ModelForm):
class Meta:
model = ContactPerson
fields = ('customer_id', 'contact_email', 'contact_no', 'collection_use_personal_data')
class EditUserCPForm(MultiModelForm):
form_classes = {
'user': EditUserForm,
'profile': UserCPForm
}
and here's my related views.py
:
def post(self, request, *args, **kwargs):
id = self.kwargs['id']
if request.user.is_superuser:
id = id
u = User.objects.get(id=id)
print(u.user_type)
u_form = None
elif u.user_type == 'ContactPerson':
print(request.POST)
u_form = EditUserCPForm(request.POST)
# p_form = UserCPForm(request.POST['profile'])
if u_form.is_valid():
print('valid')
user_form = u_form['user']
profile_form = u_form['profile']
ucp_obj = ContactPerson.objects.get(user__id=u.id)
print(ucp_obj.user.email)
ucp_obj.user.email = u_form.cleaned_data['user']['email']
print(ucp_obj.user.email)
ucp_obj.user.name = u_form.cleaned_data['user']['name']
ucp_obj.user.title = u_form.cleaned_data['user']['title']
ucp_obj.user.gender = u_form.cleaned_data['user']['gender']
ucp_obj.user.contenst = u_form.cleaned_data['user']['contenst']
ucp_obj.customer_id = u_form.cleaned_data['profile']['customer_id']
ucp_obj.contact_email = u_form.cleaned_data['profile']['contact_email']
ucp_obj.contact_no = u_form.cleaned_data['profile']['contact_no']
ucp_obj.collection_use_personal_data = u_form.cleaned_data['profile']['collection_use_personal_data']
ucp_obj.save()
u_form.save(commit=False)
print(ucp_obj.user.email)
print(id)
messages.success(request, 'success')
return HttpResponseRedirect(reverse_lazy('dashboard:dashboard-home'))
else:
messages.error(request, 'not valid data')
print(u_form.errors)
return HttpResponseRedirect(reverse_lazy('dashboard:user-edit', u.id))
else:
messages.error(request, 'you are not allowed to do so! ')
return HttpResponseRedirect(reverse_lazy('dashboard:user-edit', id))
When I edit any field from the template and submit the form, the form redirects me to the
dashboard-home
with thesuccess
message but the user in the database is not updating. what can be wrong here?
回答1:
My opinion is your not selecting the user from the database, i would have approached this the following way.
user_form = u_form['user']
profile_form = u_form['profile']
ucp_obj = ContactPerson.objects.get(user__id=u.id)
u.email = u_form.cleaned_data['user']['email']
u.name = u_form.cleaned_data['user']['name']
u.title = u_form.cleaned_data['user']['title']
u.gender = u_form.cleaned_data['user']['gender']
u.contenst = u_form.cleaned_data['user']['contenst']
u.save()
ucp_obj.customer_id = u_form.cleaned_data['profile']['customer_id']
ucp_obj.contact_email = u_form.cleaned_data['profile']['contact_email']
ucp_obj.contact_no = u_form.cleaned_data['profile']['contact_no']
ucp_obj.collection_use_personal_data = u_form.cleaned_data['profile']['collection_use_personal_data']
ucp_obj.user = u
ucp_obj.save()
messages.success(request, 'success')
return HttpResponseRedirect(reverse_lazy('dashboard:dashboard-home'))
来源:https://stackoverflow.com/questions/59442964/python-update-a-user-in-django-2-2