通过管理界面更改密码表单时出现自定义用户模型错误

时间:2019-05-16 03:41:05

标签: django django-models django-custom-user django-2.2

试图在django项目开始时设置自定义用户模型,但是我面临一个经常出现的问题,即我只能进行修补,现在正在影响管理界面的changepassword。提交更改密码表单后,它崩溃并显示错误:

AttributeError at /admin/custom_users/customuser/7/password/

'NoneType' object has no attribute 'strip'

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/custom_users/customuser/7/password/

Django Version: 2.2
Python Version: 3.7.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'cashflow.apps.CashflowConfig',
 'custom_users.apps.CustomUsersConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/connection_cext.py" in cmd_query
  395.                                raw_as_string=raw_as_string)

During handling of the above exception (Column 'is_superuser' cannot be null), another exception occurred:

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/base.py" in _execute_wrapper
  168.             return method(query, args)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/cursor_cext.py" in execute
  266.                                          raw_as_string=self._raw_as_string)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/connection_cext.py" in cmd_query
  398.                                              sqlstate=exc.sqlstate)

During handling of the above exception (1048 (23000): Column 'is_superuser' cannot be null), another exception occurred:

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/backends/utils.py" in execute
  99.             return super().execute(sql, params)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/backends/utils.py" in execute
  67.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
  76.         return executor(sql, params, many, context)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/backends/utils.py" in _execute
  84.                 return self.cursor.execute(sql, params)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/base.py" in execute
  218.         return self._execute_wrapper(self.cursor.execute, query, new_args)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/base.py" in _execute_wrapper
  174.                         utils.IntegrityError(err.msg), sys.exc_info()[2])

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/utils/six.py" in reraise
  683.             raise value.with_traceback(tb)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/base.py" in _execute_wrapper
  168.             return method(query, args)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/cursor_cext.py" in execute
  266.                                          raw_as_string=self._raw_as_string)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/connection_cext.py" in cmd_query
  398.                                              sqlstate=exc.sqlstate)

During handling of the above exception (Column 'is_superuser' cannot be null), another exception occurred:

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/cursor_cext.py" in statement
  606.             return self._executed.strip().decode('utf8')

During handling of the above exception ('NoneType' object has no attribute 'strip'), another exception occurred:

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
  76.             return view(request, *args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/contrib/auth/admin.py" in user_change_password
  141.                 form.save()

File "/home/mh/devel/dreamit_control/dcontrol/custom_users/forms.py" in save
  32.             self.user.save()

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/contrib/auth/base_user.py" in save
  66.         super().save(*args, **kwargs)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/base.py" in save
  741.                        force_update=force_update, update_fields=update_fields)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/base.py" in save_base
  779.                 force_update, using, update_fields,

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/base.py" in _save_table
  851.                                       forced_update)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/base.py" in _do_update
  900.         return filtered._update(values) > 0

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/query.py" in _update
  760.         return query.get_compiler(self.db).execute_sql(CURSOR)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1426.         cursor = super().execute_sql(result_type)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1097.             cursor.execute(sql, params)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/django/db/backends/utils.py" in execute
  103.             sql = self.db.ops.last_executed_query(self.cursor, sql, params)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/operations.py" in last_executed_query
  127.         return force_text(cursor.statement, errors='replace')

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/django/base.py" in __getattr__
  230.         return getattr(self.cursor, attr)

File "/home/mh/devel/dreamit_control/env/lib/python3.7/site-packages/mysql/connector/cursor_cext.py" in statement
  608.             return self._executed.strip()

Exception Type: AttributeError at /admin/custom_users/customuser/7/password/
Exception Value: 'NoneType' object has no attribute 'strip'

在堆栈跟踪中,我可以看到问题是尝试查询时is_staff = NULL和is_superuser = NULL。

我不知道为什么django会在passwordchange时将此参数传递为null,因为在模型上将它们设置为false,而在CustomUserPassForm上它们都不是字段。在用户更改表单上也有同样的问题,但是在将字段集添加到CustomUserAdmin(UserAdmin)类之后,我能够编辑用户。 (因为is_superuser和is_staff输入复选框出现在html的表单中)

models.py

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('correo es obligatorio')
        email = self.normalize_email(email)
        extra_fields.setdefault('is_superuser', False)
        extra_fields.setdefault('is_staff', False)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('superuser must have is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('superuser musthave is_superuser=True')
        return self.create_user(email, password, **extra_fields)

class CustomUser(AbstractUser, PermissionsMixin):
    cargo = models.TextField(max_length=50, null=True)
    rut = models.IntegerField(null=True)
    DIGITO_VERIFICADOR_CHOICES = (
        ('1','1'),
        ('2','2'),
        ('3','3'),
        ('4','4'),
        ('5','5'),
        ('6','6'),
        ('7','7'),
        ('8','8'),
        ('9','9'),
        ('0','0'),
        ('K','K')
    )
    digito_verificador = models.CharField(max_length=1, choices=DIGITO_VERIFICADOR_CHOICES, null=True)
    nombre = models.CharField(max_length=25, default="john")
    apellido = models.CharField(max_length=25, default="doe")
    email = models.EmailField(verbose_name='correo', max_length=255, unique=True)
    username = models.TextField(max_length=255, null=True)
    is_superuser = models.BooleanField(default=False, blank=True)
    is_staff = models.BooleanField(default=False, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

forms.py

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = get_user_model()
        fields = ['email', 'rut', 'digito_verificador',]

class CustomUserChangeForm(UserChangeForm):

    rut = forms.IntegerField(min_value=1000000)
    #is_superUser = forms.BooleanField()
    class Meta:
        model = get_user_model()
        fields =  ['rut', 'digito_verificador',]
        #['email', 'is_superuser','is_staff' ]


class CustomUserPassForm(AdminPasswordChangeForm):
#    is_staff = forms.BooleanField(initial=False)
 #   is_superuser = forms.BooleanField(initial=False)

    #fields = ['is_staff','is_superuser']
    def save(self, commit=True):
        password = self.cleaned_data["password1"]
        self.user.set_password(password)
        print(self.user)
        if commit:
            self.user.save()
        return self.user

admin.py

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    change_password_form = CustomUserPassForm
    model = get_user_model()
    list_display = ['email', ]
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('personal info',{'fields': ('nombre', 'apellido',('rut','digito_verificador'))}),
        ('permissions', {'fields':('is_superuser', 'is_staff')})
    )
    add_fieldsets = (
        (None, {
            'classes':('wide',),
            'fields':('email', 'password1', 'password2'),
        }
        ),
    )

admin.site.register(CustomUser, CustomUserAdmin)

已经花了两天时间阅读教程和文档,包括官方的django指南,所有这些都省略了有关change_password_form实施的信息。

1 个答案:

答案 0 :(得分:0)

问题是CustomUserPassForm的save方法。由于某些原因(我尚未完成完整的后续工作),用户属性将is_staff和is_superuser设置为NULL。迫使这些错误修补了问题。

class CustomUserPassForm(AdminPasswordChangeForm):

    def save(self, commit=True):
        password = self.cleaned_data["password1"]
        self.user.set_password(password)
        self.user.is_staff = False
        self.user.is_superuser = False

        if commit:
            self.user.save()

        return self.user

现在,如果有人可以阐明为什么,我将不胜感激(以及如何将is_staff和is_superuser设置为与db中实际保持的相同值)。