"'NoneType' object is not iterable" when adding new user on django custom user model

2.1k views Asked by At

First of all, I am new to Django. Please tell me if my question is not clear and straightforward.

I was trying to make custom user model for my app, everything seems fine until I found error when trying to add new user in the admin page. The error page was shown after I clicked Add User button on the top right of the page.

*Note:

  1. I am using Django 1.10.8
  2. I created it in the app named 'accounts'
  3. I am trying to get rid of username field (Django's default) and changed it to phone_number as the unique field.
  4. I can create superuser (with python manage.py createsuperuser), I can edit it also.

This is the error:



    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

this is my models.py codes:

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

and this is my admin.py code:

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)

Any kind of help would be appreciated. Thank you.

1

There are 1 answers

4
Satevg On BEST ANSWER

I guess you need to add comma after the first tuple, in add_fieldsets. Try to copy following piece of code.

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

Checked it in console:

>>> 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

This is more pythonic problem, not django's. So you won't find answer in django documentation. Here's the function where the error was. To bring you an idea, I'll leave this example:

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