Unexpected keyword in createsuperuser django

I am working with BaseAbstractUser and AbstractUser, and I have a problem with a required field.

models.py

from django.db import models
from django.conf import settings
from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager
from django.utils.timezone import timedelta, now
from django.core.exceptions import ValidationError

# File validation function
def validate_file_type(value):
    allowed_types = ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]
    if value.content_type not in allowed_types:
        raise ValidationError("Only PDF and Word documents are allowed.")

class CustomUserManager(BaseUserManager):
    """Manager for CustomUser"""

    def create_user(self, email, password=None, role="customer"):
        if not email:
            raise ValueError("Users must have an email address")
        user = self.model(email=self.normalize_email(email), role=role)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None):
        user = self.create_user(email, password, role="admin")
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

class CustomUser(AbstractBaseUser):
    """Custom user model using email authentication"""
    ROLE_CHOICES = [
        ("vendor", "Vendor"),
        ("customer", "Customer"),
        ("admin", "Admin"),
    ]

    email = models.EmailField(unique=True)
    role = models.CharField(max_length=10, choices=ROLE_CHOICES, default="customer")
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)  # Required for Django admin
    is_superuser = models.BooleanField(default=False)  # Required for superuser checks

    objects = CustomUserManager()  # Use the custom manager

    USERNAME_FIELD = "email"  # Set email as the primary login field
    REQUIRED_FIELDS = ["role"]

    def __str__(self):
        return self. Email

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth import get_user_model

CustomUser = get_user_model()

class CustomUserAdmin(UserAdmin):
    """Admin panel customization for CustomUser"""
    model = CustomUser
    list_display = ("email", "role", "is_staff", "is_active")
    ordering = ("email",)
    search_fields = ("email",)

    fieldsets = (
        (None, {"fields": ("email", "password")}),
        ("Roles & Permissions", {"fields": ("role", "is_staff", "is_superuser", "is_active")}),
    )

    add_fieldsets = (
        (None, {
            "classes": ("wide",),
            "fields": ("email", "role", "password1", "password2", "is_staff", "is_superuser", "is_active")
        }),
    )

    # Remove `groups` since it's not part of CustomUser
    filter_horizontal = []  # Instead of filter_horizontal = ["groups"]
    list_filter = ("role", "is_staff", "is_active")  # No 'groups'

admin.site.register(CustomUser, CustomUserAdmin)

When I ran python manage.py createsuperuser, it asked for my email, password, and role, which is what I expected it to do. However, when I hit return, it said that the role is an unexpected keyword. How do I fix this?

The Error:

Traceback (most recent call last):
  File "/PycharmProjects/RFPoject2/manage.py", line 22, in <module>
    main()
  File "/PycharmProjects/RFPoject2/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility. Execute()
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 416, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 90, in execute
    return super().execute(*args, **options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 460, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/PycharmProjects/RFPoject2/.venv/lib/python3.11/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 239, in handle
    self.UserModel._default_manager.db_manager(database).create_superuser(
TypeError: CustomUserManager.create_superuser() got an unexpected keyword argument 'role'

Does CreatSuperUser require something special to make this work? Thanks!

Add a rule='admin' parameter to the create_superuser(..) method, we can add an extra check that it is indeed admin:

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, role="customer", **kwargs):
        if not email:
            raise ValueError("Users must have an email address")
        user = self.model(email=self.normalize_email(email), role=role, **kwargs)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, role='admin', **kwargs):
        assert role == 'admin'
        user = self.create_user(email, password, role="admin", **kwargs)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

Since you have set a default value for role, i don't think it is necessary to add it in required_fields.

Especially if you apply the advice of Mr @willeM_ Van Onsem which seems to be a good solution to your problem.

Вернуться на верх