Django:如何在不更新用户密码字段的情况下更新用户模型

时间:2017-12-20 19:31:34

标签: python django django-forms

我尝试创建仅更新用户的选择字段的用户更新端点。我目前的实现是使用ModelForm的保存方法保存模型,但我也尝试使用基本模型保存方法。

我的请求正文中没有包含密码字段,而且我的UserForm中没有密码字段,但是我无法维护当前会话或注销并重新登录执行更新后的当前用户。我几乎是肯定的,因为Django在更新过程中某处更改了我的密码。

其他相关信息:我使用的是Django(不是Django Rest Framework)。我有一个自定义用户模型。我知道我可以通过使用带有DRF的序列化器来解决这个问题,但仅仅针对这个问题使用它似乎很麻烦。

我的端点如下所示:

def saveAccountData (request):
    resp = {}
    if request.method == 'POST':
        form = UserForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()

            resp['result'] = 'User updated'
            return HttpResponse(
                json.dumps(resp),
                status=200
            )
        else:
            return HttpResponse(
                json.dumps(form.errors),
                status=422,
            )

我的表格如下:

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['email', 'name', 'is_active', 'is_admin']

    def save(self, commit=True):
        user = super(UserForm, self).save(commit=False)
        user.name = self.cleaned_data['name']

        if commit:
            user.save()
        return user

用户模型:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.conf import settings
import logging

class UserManager(BaseUserManager):

    def create_user(self, email, name, password=None):
        # executes if email is zero (false) or an empty container (equivalent to None)
        logger = logging.getLogger(__name__)
        logger.warning('Create user: ' + password)
        if not email:
            raise ValueError("Please provide an email address")

        if not password:
            raise ValueError("Please enter a password")

        if not name:
            raise ValueError("Please enter your name")

        # normalize email address (convert to lower case so all email addresses are standardized)
        user = self.model(
            email = self.normalize_email(email),
            name=name,
        )
        # the set_password method encrypts the password
        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_superuser(self, email, password, name):
        user = self.create_user(
            email, 
            password=password, 
            name=name)

        user.is_superuser = True
        user.is_admin = True
        user.save(using=self._db)

        return user

class User(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(max_length=50, unique=True)
    password = models.CharField(max_length=100)
    name = models.CharField(max_length=100)
    phone = models.CharField(max_length=20)
    city = models.CharField(max_length=50)
    state = models.CharField(max_length=20)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()
    # we must specify a username field
    USERNAME_FIELD = 'email'
    # required fields are used for create_superuser
    REQUIRED_FIELDS = ['name']

    def get_full_name(self):
        return self.name

    def get_short_name(self):
        return self.name

    def __str__(self):
        # django uses this method when it needs to convert an object to a string
        return self.email

1 个答案:

答案 0 :(得分:0)

我创建了一个UpdateAccountForm(forms.ModelForm), 并像这样覆盖save():

```

  class Meta:
      model = User
      fields = ['username', 'groups', 'is_active']

  def save(self, commit=True):
  ┆   user = super(UpdateAccountForm, self).save(commit=False)
  ┆   password = self.cleaned_data["password"]
  ┆   if password:
  ┆   ┆   user.set_password(password)
  ┆   if commit:
  ┆   ┆   user.save()
  ┆   return user

```