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’
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
- Difference between is_staff and is_superuser
- Corrected Code
- Additional Access Control Settings
- Best Practices for Working with Users
- Debugging Similar Errors
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:
is_stuff: bool = False, # Incorrect
and
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:
@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:
# When creating a superuser:
is_staff=True,
is_superuser=True
Best Practices for Working with Users
- Use user factories as in your example - this is a good approach for tests
- Always check field names before using them in creation methods
- Document access levels in your project
- Use groups for complex permission systems
- Regularly update Django for the latest security improvements
Debugging Similar Errors
When encountering a TypeError with unexpected arguments:
- Check for typos - the most common cause of such errors
- Consult the documentation for the model you’re using
- Use autocomplete in IDEs to prevent errors
- 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_nameis_staff,is_superuser,is_activedate_joined,last_login
Sources
- Django Official Documentation - User model
- Stack Overflow - Difference between staff, admin, superuser in Django
- Django Forum - Understanding of User
is_stafffield - Why does Django use is_staff and is_superuser
- 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.