【问题标题】:"'NoneType' object is not iterable" when adding new user on django custom user model在 django 自定义用户模型上添加新用户时,“'NoneType' 对象不可迭代”
【发布时间】:2023-03-10 09:20:01
【问题描述】:

首先,我是 Django 新手。如果我的问题不清楚和直截了当,请告诉我。

我正在尝试为我的应用程序制作自定义用户模型,但在我尝试在管理页面中添加新用户时发现错误之前,一切似乎都很好。单击页面右上角的添加用户按钮后,将显示错误页面。

*注意:

  1. 我使用的是 Django 1.10.8
  2. 我在名为“accounts”的应用中创建了它
  3. 我正在尝试删除用户名字段(Django 的默认值)并将其更改为 phone_number 作为唯一字段。
  4. 我可以创建超级用户(使用 python manage.py createsuperuser),我也可以编辑它。

这是错误:



    Environment:

    Request Method: GET
    Request URL: http://localhost:8002/admin/accounts/user/add/

    Django Version: 1.10.8
    Python Version: 2.7.10
    Installed Applications:
    ['django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'accounts.apps.AccountsConfig']
    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 "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
      42.             response = get_response(request)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
      187.                 response = self.process_exception_by_middleware(e, request)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
      185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
      544.                 return self.admin_site.admin_view(view)(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
      149.                     response = view_func(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
      57.         response = view_func(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
      211.             return view(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
      67.             return bound_func(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
      76.             return view(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
      63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
      67.             return bound_func(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
      149.                     response = view_func(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
      63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in inner
      185.                     return func(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/auth/admin.py" in add_view
      128.                                                extra_context)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
      1509.         return self.changeform_view(request, None, form_url, extra_context)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
      67.             return bound_func(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
      149.                     response = view_func(request, *args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
      63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/utils/decorators.py" in inner
      185.                     return func(*args, **kwargs)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/options.py" in changeform_view
      1438.         ModelForm = self.get_form(request, obj)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/auth/admin.py" in get_form
      82.         return super(UserAdmin, self).get_form(request, obj, **defaults)

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/options.py" in get_form
      608.             fields = flatten_fieldsets(self.get_fieldsets(request, obj))

    File "/Users/user/Documents/adxasia/jani_backend/lib/python2.7/site-packages/django/contrib/admin/utils.py" in flatten_fieldsets
      112.     for name, opts in fieldsets:

    Exception Type: TypeError at /admin/accounts/user/add/
    Exception Value: 'NoneType' object is not iterable

这是我的 models.py 代码:



from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager
)


class UserManager(BaseUserManager):
    use_in_migrations = True

    def create_user(self, phone_number, password=None):
        """
        For creating users
        """
        if not phone_number:
            raise ValueError('User must have phone number!')
        if not password:
            raise ValueError('User must have password!')

        user = self.model(
            phone_number = phone_number,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, phone_number, password, first_name, last_name):
        """
        For creating user staff
        """
        user = self.create_user(
            phone_number,
            password=password,
        )
        user.staff = True
        user.active = True
        user.save(using=self._db)
        return user

    def create_superuser(self, phone_number, first_name, last_name, password):
        """
        For creating super user
        """
        user = self.create_user(
            phone_number,
            password=password,
        )
        user.admin = True
        user.staff = True
        user.active = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    phone_number = models.CharField(max_length=15, unique=True)
    active = models.BooleanField(default=False)
    staff = models.BooleanField(default=False)
    admin = models.BooleanField(default=False)

    first_name = models.CharField(max_length=50, blank=True, null=True)
    last_name = models.CharField(max_length=50, blank=True, null=True)
    address = models.CharField(max_length=255, blank=True, null=True)
    birth_date = models.DateField(blank=True, null=True)
    avatar = models.ImageField(blank=True, null=True)

    objects = UserManager()

    USERNAME_FIELD = 'phone_number'
    REQUIRED_FIELDS = []


    def __str__(self):
        return self.full_name

    def get_full_name(self):
        # The user is identified by their phone number
        return self.phone_number

    def get_short_name(self):
        # The user is identified by their phone number
        return self.phone_number

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def full_name(self):
        return self.first_name + ' ' + self.last_name

    @property
    def is_active(self):
        "Is the user active?"
        return self.active

    @property
    def is_staff(self):
        "Is the user member of staff?"
        return self.staff

    @property
    def is_admin(self):
        "Is the user member of admin?"
        return self.admin

这是我的 admin.py 代码:



from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin


User = get_user_model()


class UserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('phone_number', 'password')}),
        ('Bio', {'fields': ('first_name', 'last_name', 'address', 'birth_date')})
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('phone_number', 'password1', 'password2')
        })
    )

    search_fields = ('phone_number', 'full_name')
    list_display = ('phone_number', 'full_name', 'admin', 'staff', 'active')
    list_filter = ('admin', 'staff', 'active')
    ordering = ('phone_number',)
    filter_horizontal = ()


admin.site.register(User, UserAdmin)
admin.site.unregister(Group)

任何形式的帮助将不胜感激。谢谢。

【问题讨论】:

    标签: python django django-custom-user django-custom-manager


    【解决方案1】:

    我猜你需要在add_fieldsets 的第一个元组之后添加逗号。尝试复制以下代码。

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('phone_number', 'password1', 'password2')
        }),
    )
    

    在控制台中检查:

    >>> from django.contrib.admin.utils import flatten_fieldsets
    >>> add_fieldsets = ((None, {'classes': ('wide',), 'fields': ('phone_number', 'password1', 'password2')}))
    >>> flatten_fieldsets(add_fieldsets)
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/home/yauheni/Dev/clean_django/venv/lib/python3.6/site-packages/django/contrib/admin/utils.py", line 112, in flatten_fieldsets
        for name, opts in fieldsets:
    TypeError: 'NoneType' object is not iterable
    >>> add_fieldsets = ((None, {'classes': ('wide',), 'fields': ('phone_number', 'password1', 'password2')}),)
    >>> flatten_fieldsets(add_fieldsets)
    ['phone_number', 'password1', 'password2']
    >>> 
    

    UPD

    这是更多的pythonic问题,而不是django的。所以你不会在 django 文档中找到答案。这是错误所在的function。为了给你带来一个想法,我将留下这个例子:

    >>> x = ((1, 2))
    >>> x[0]
    1
    >>> x = ((1, 2),)
    >>> x[0]
    (1, 2)
    

    【讨论】:

    • 您的解决方案完美运行,谢谢!你能告诉我为什么会这样吗?我稍后会检查文档。
    • @TijaniRF 更新了答案并简要说明了原始问题
    • 我的错,那是菜鸟的错误。感谢您的更新!
    • 这实际上是一个众所周知的python陷阱:文字元组由尾随逗号而不是括号定义 - 除了由一对括号定义的空元组,并且您仍然需要某些地方的括号可以消除表达式的歧义(即,如果您想在逗号有另一种含义的表达式中使用文字元组 - 函数调用、元组的文字列表等)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2022-08-12
    • 2020-08-23
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    相关资源
    最近更新 更多