NeuroAgent

Django is_staff Error: Fix and Difference with is_superuser

Fix TypeError when creating users in Django. Difference between is_staff and is_superuser, correct code, and best practices.

Question

Why does Django throw a TypeError: User() got unexpected keyword arguments: ‘is_stuff’ when using the is_stuff argument in the create method?

@pytest.fixture
def user_factory(db):
def create_user(
username: str,
password: str = ‘11’,
first_name: str = ‘foo’,
last_name: str = ‘bar’,
email: str = ‘foo@bar.com’,
is_stuff: bool = False,
is_superuser: bool = False,
is_active: bool = True
):
user = User.objects.create(
username=username,
password=password,
first_name=first_name,
last_name=last_name,
email=email,
is_stuff=is_stuff,
is_superuser=is_superuser,
is_active=is_active
)
return user

return create_user

@pytest.fixture
def user_mikelee(db, user_factory):
return user_factory(‘mikelee’)

The code raises

TypeError: User() got unexpected keyword arguments: ‘is_stuff’

NeuroAgent

The error occurs due to a typo in the field name - you’re using is_stuff instead of the correct is_staff. In Django’s User model, the expected field is is_staff (with the letter ‘a’), not is_stuff (with the letter ‘u’), which causes a TypeError when creating a user.

Contents

Main Cause of the Error

The TypeError: User() got unexpected keyword arguments: 'is_stuff' error occurs because you’re trying to pass a non-existent parameter is_stuff to the User.objects.create() method. The correct field name in Django’s User model is is_staff (with the letter ‘a’, not ‘u’).

Important: Django’s User model has a fixed set of fields, and any deviation in the name causes a TypeError. This is standard Python behavior when working with objects.

In your code, the problem is in the line:

python
is_stuff: bool = False,  # Incorrect

and

python
is_stuff=is_stuff,  # Incorrect

Difference between is_staff and is_superuser

Based on the official Django documentation and research, let’s break down the difference between these two important fields:

Field Purpose Access Rights
is_staff Grants access to Django’s admin interface Can log into admin but doesn’t have all rights
is_superuser Provides all system permissions Has full access, can manage users and permissions

As explained in the Django documentation, “a superuser is just a convenient way of creating a user with all permissions”. While is_staff only allows access to the admin interface.

Quote from Stack Overflow: “Any user with the staff flag can log into the admin application. Beyond that, they have no other special privileges. A superuser is just a convenient way of creating a user with all permissions”.

Corrected Code

Here’s the corrected version of your code:

python
@pytest.fixture
def user_factory(db):
    def create_user(
            username: str,
            password: str = '11',
            first_name: str = 'foo',
            last_name: str = 'bar',
            email: str = 'foo@bar.com',
            is_staff: bool = False,  # CORRECTED: is_stuff -> is_staff
            is_superuser: bool = False,
            is_active: bool = True
    ):
        user = User.objects.create(
            username=username,
            password=password,
            first_name=first_name,
            last_name=last_name,
            email=email,
            is_staff=is_staff,  # CORRECTED: is_stuff -> is_staff
            is_superuser=is_superuser,
            is_active=is_active
        )
        return user
    
    return create_user

After this correction, the code will work correctly, and you’ll be able to create users with different access levels.

Additional Access Control Settings

When working with users in Django, it’s useful to know additional aspects:

1. is_active field

As noted in discussions on the Django Forum, the is_active field relates to the entire Django authentication system, not just the admin. Inactive users cannot log into the system.

2. Groups and permissions

Django provides a flexible system for managing permissions:

  • Groups - allow grouping users by roles
  • Permissions - detailed control over actions

3. Creating a superuser

When running the python manage.py createsuperuser command, Django automatically sets both fields to True:

python
# When creating a superuser:
is_staff=True,
is_superuser=True

Best Practices for Working with Users

  1. Use user factories as in your example - this is a good approach for tests
  2. Always check field names before using them in creation methods
  3. Document access levels in your project
  4. Use groups for complex permission systems
  5. Regularly update Django for the latest security improvements

Debugging Similar Errors

When encountering a TypeError with unexpected arguments:

  1. Check for typos - the most common cause of such errors
  2. Consult the documentation for the model you’re using
  3. Use autocomplete in IDEs to prevent errors
  4. Enable detailed Django errors for better problem understanding

For Django’s User model, it’s helpful to remember the main fields:

  • username, email, password, first_name, last_name
  • is_staff, is_superuser, is_active
  • date_joined, last_login

Sources

  1. Django Official Documentation - User model
  2. Stack Overflow - Difference between staff, admin, superuser in Django
  3. Django Forum - Understanding of User is_staff field
  4. Why does Django use is_staff and is_superuser
  5. Django Ticket #23559 - Staff permissions management

Conclusion

The TypeError with is_stuff is a common typo that’s easily fixed by replacing it with the correct is_staff. It’s important to understand the difference between these fields:

  • is_staff - access to admin interface
  • is_superuser - all system permissions

The corrected code will work properly, and your tests will be able to create users with different access levels. Always check field names and use the official Django documentation as your primary source of information about the User model structure.