试图在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实施的信息。
答案 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中实际保持的相同值)。