Ошибка пользовательской модели пользователя при смене пароля через интерфейс администратора - PullRequest
0 голосов
/ 16 мая 2019

Попытка настроить пользовательскую модель при запуске проекта django, но я сталкиваюсь с повторяющейся проблемой, которую я только смог исправить, которая теперь влияет на пароль изменения интерфейса администратора.При отправке формы изменения пароля происходит сбой с ошибкой:

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 передает эти параметры как нулевые при смене пароля, так как они установлены в 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 голосов
/ 16 мая 2019

Проблема была в методе сохранения CustomUserPassForm.По какой-то причине (я не выполнил полное продолжение) пользовательский атрибут имел 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.)

...