0

我创建一个用户配置文件如下:

class UserProfile(models.Model):
    # This field is required:
    user = models.OneToOneField(User, related_name="User can view study permission")  
    # Other fields:
    phone = models.CharField(max_length=20)
    disease = models.ManyToManyField(Disease) 
    date_assigned = models.DateTimeField("Date Assigned")
    query = models.ManyToManyField(Query, blank=True) 

    def __unicode__(self):
        studies = ', '.join(study.name for study in self.disease.all())
        return "%s can view %s" % (self.user, studies)

它是用户的扩展信息。现在我正在自己创建一个管理页面,以允许管理员更新包含上述用户配置文件的用户帐户信息。其形式和代码如下:

def edit(request, user_id):
"""Edit a user's details"""
try:
  user = User.objects.get(id=user_id)
except User.DoesNotExist:
  user = None

# user exists:    
if user:
# Initial form field data:
  initial={'user_id': user_id,
         'username': user.username,
         'fname': user.first_name,
         'lname': user.last_name,
         'email': user.email,
         'phone': user.get_profile().phone,
         'groups': user.groups.all(),
         'studies': user.get_profile().disease.all(),
         'is_admin': user.is_staff,
         'is_active': user.is_active
         }

request.breadcrumbs(
  (_("Home"), reverse('home')),
  (_("All Users"), reverse('all users')),
  (_("User Details"), reverse('user details', args=[user_id])), 
)

if request.method == "GET":
  form = UserProfileEditForm(initial=initial,extra=request.user.id)
  response = {'heading': 'Edit', 'form': form}
  return render_to_response('accounts/edit.html',
                            response,
                            context_instance=RequestContext(request)
                            )
elif request.method == "POST":
  form = UserProfileEditForm(request.POST,extra=request.user.id)
  if form.is_valid():
    Log().add(request, "Edit", "W", "userprofile", user_id)

    if form.cleaned_data['password1'] and form.cleaned_data['password2']:
      user.set_password(form.cleaned_data['password1'])
    user.username = form.cleaned_data['username']
    user.first_name = form.cleaned_data['fname']
    user.last_name = form.cleaned_data['lname']
    user.email = form.cleaned_data['email']
    user.groups = form.cleaned_data['groups']
    user.is_staff = form.cleaned_data['is_admin']
    user.is_active = form.cleaned_data['is_active']
    user.save()

    # Oddly to make the extra fields found in UserProfile are saved, you
    # have to call get_profile().ATTRIBUTE, assign a value, then call
    # get_profile().save(). Calling user.save() as the last step won't 
    # save any changes made to UserProfile:
    disease_pks = form.cleaned_data['studies']
    user.get_profile().disease = Disease.objects.filter(pk__in=disease_pks)
    user.get_profile().phone = form.cleaned_data['phone']
    user.get_profile().save()

    return HttpResponseRedirect("/accounts/view/%s" % user_id)
  else:
    # form is not valid:
    return render_to_response("accounts/edit.html",
                              {'form': form, 'heading': 'Edit'},
                              context_instance=RequestContext(request)
                              )
# user does not exist:
else:
  error = "User #%s cannot be found. Press the 'BACK' button on your browser." % user_id 
  return HttpResponseRedirect(reverse('DigitalRecords.views.error', args=(error,)))

class UserProfileEditForm(forms.Form):
user_id = forms.IntegerField(widget=forms.HiddenInput())
username = forms.CharField(label=_("Username"))
password1 = forms.CharField(label=_("Password"), 
                          widget=forms.PasswordInput(),
                          required=False
                          )
password2 = forms.CharField(label=_("Password (again)"), 
                          widget=forms.PasswordInput(),
                          required=False
                          )  
fname = forms.CharField(label=_("First name"))
lname = forms.CharField(label=_("Last name"))
email = forms.EmailField()
phone = forms.CharField(label=_("Phone"))
is_admin = forms.BooleanField(label=_("Is an administrator?"), required=False)
is_active = forms.BooleanField(label=_("Is an active user?"), required=False)
groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(),
                                      widget=forms.CheckboxSelectMultiple()
                                      )
#Attach a form helper to this class
helper = FormHelper()
helper.form_id = "edituserprofile"
helper.form_class = "userprofile"

#Add in a submit and reset button
submit = Submit("Save", "Save Changes")
helper.add_input(submit)
reset = Reset("Reset", "Reset")
helper.add_input(reset)

def __init__(self, *args,**kwargs):
  extra = kwargs.pop('extra')
  super(UserProfileEditForm, self).__init__(*args, **kwargs)
  self.fields["studies"] =        forms.ModelMultipleChoiceField(queryset=User.objects.get(id=extra).get_profile().disease.all(),
                                       widget=forms.CheckboxSelectMultiple()
                                       ) 

def clean_username(self):
  """Check if the username does not already exist"""
  username = self.cleaned_data['username']
  user_id = self.cleaned_data['user_id']

  # handle:
  try:
    user = User.objects.get(username=username)
  except User.DoesNotExist:
    return self.cleaned_data['username']
  else:
    if user.id == user_id:
      return self.cleaned_data['username']
    else:  
      raise forms.ValidationError('User "%s" already exists' % username)

def clean_fname(self):

  fname = self.cleaned_data['fname']
  # Remove any diacritics/accented characters:
  fname = strip_diacritic(fname).strip()
  # Match names that may have hyphens, apostrophes, or periods in them.
  # example: John Doe, O'Brien, Leroy-Brown, Cpt. James T. Kirk
  pattern = '^([a-zA-Z]+(?:\.)?(?:[\-\' ][a-zA-Z]+(?:\.)?)*)$'

  # match the regex to the input string.
  results = re.match(pattern, str(fname))

  if results == None:
    raise ValidationError(u'%s is not a valid name' % fname)
  return fname

def clean_lname(self):
  """
  Determine if the patient's name is valid. It removed any accented/diacritic 
  characters and replaces them with the base character for simplicity. Names with 
  hyphens and/ore apostrophes like Hanna-Barbara and O'Brien are allowed. If the 
  check fails a validation error is raised.
  """ 
  lname = self.cleaned_data['lname']    
  # Remove any diacritics/accented characters:
  lname = strip_diacritic(lname).strip()    
  # Match names that may have hyphens, apostrophes, or periods in them.
  # example: John Doe, O'Brien, Leroy-Brown, Cpt. James T. Kirk
  pattern = '^([a-zA-Z]+(?:\.)?(?:[\-\' ][a-zA-Z]+(?:\.)?)*)$'

  # match the regex to the input string.
  results = re.match(pattern, str(lname))

  if results == None:
    raise ValidationError(u'%s is not a valid name' % lname)
  return lname

def clean(self):
  """Check if password1 and password2 match"""
  cleaned_data = self.cleaned_data
  password1 = cleaned_data.get('password1')
  password2 = cleaned_data.get('password2')

  # Notice it's an 'or' condition because a password change is optional:
  if password1 or password2:
    if password1 != password2:
      msg = "Passwords do not match"
      self._errors['password1'] = self.error_class([msg])
      self._errors['password2'] = self.error_class([msg])
      del cleaned_data['password1']
      del cleaned_data['password2']
      return cleaned_data
  return self.cleaned_data

如果管理员试图编辑其他用户的帐户信息,它可以正常工作。但是,当管理员尝试更新他自己的帐户时。无论此字段是否更改,疾病字段将始终为空白。

有谁知道原因以及我应该如何更改我的代码?非常感谢。

4

1 回答 1

0

我不确定其他代码,但您认为这些行似乎不合适。

user.get_profile().disease = Disease.objects.filter(pk__in=disease_pks)
user.get_profile().phone = form.cleaned_data['phone']
user.get_profile().save()

您每次都通过调用user.get_profile()和更新它来获取新的配置文件对象。不保存它,而是一个新对象。所以改成

profile = user.get_profile()
profile.disease = Disease.objects.filter(pk__in=disease_pks)
profile.phone = form.cleaned_data['phone']
profile.save() 
于 2013-02-28T17:06:43.970 回答