Home > Net >  Ask model field only in creating user not super user. (Django)
Ask model field only in creating user not super user. (Django)

Time:10-05

I am making a college - student contacting Django app.

Question : I wanted my Django app to not ask for "roll_number" when creating a superuser which it does not, but I am still getting this error (the error is at the bottom) and I can't make it null or blank because I want it to be asked in the Django form for student registering. How do I do it?

The code :

  • model.py
#accounts/models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, UserManager
from .manager import UserManager

# AbstractUser can also be used because it already has some predefined model fields
# and we can add more if we want to.
class Account(AbstractBaseUser):
    # choices for department
    class Department(models.TextChoices):
        CSE = "COMPUTER SCIENCE"
        IT = "INFORMATION TECHNOLOGY"
        EE = "ELECTRIC ENGINEERING"
        CE = "CIVIL ENGINEERING"
        TE = "TEXTILE ENGINEERING"
        ME = "MECHANICAL ENGINEERING"
        OT = "OTHER"

    email = models.EmailField(max_length=100, unique=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    roll_number = models.CharField(max_length=10, unique=True)

    department = models.CharField(
        max_length=30,
        choices=Department.choices,
        default=Department.OT,
    )

    # required
    date_joined = models.DateTimeField(auto_now=True)
    last_login = models.DateTimeField(auto_now_add=True)
    is_admin = models.BooleanField(default=False)
    is_superadmin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    USERNAME_FIELD: str = "email"
    REQUIRED_FIELDS = ["first_name", "last_name", "department"]

    object = UserManager()

    def __str__(self) -> str:
        if self.roll_number and self.username:
            return "{} - {}".format(self.email, self.roll_number)

        else:
            return self.email

    # must add in
    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, add_label):
        return True


  • manager.py
from django.contrib.auth.models import BaseUserManager


class UserManager(BaseUserManager):
    def create_user(self, email, first_name, last_name, roll_no, password):
        if not email:
            raise ValueError("User requires an Email")
        if not first_name:
            raise ValueError("User requires a First name")
        if not roll_no:
            raise ValueError("User requires a Roll Number")

        user = self.model(
            email=self.normalize_email(email),
            first_name=first_name,
            last_name=last_name,
            roll_no=roll_no,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(
        self, email, first_name, last_name, password, department="OTHER"
    ):
        if not email:
            raise ValueError("Admin requires an Email")
        if not first_name:
            raise ValueError("Admin requires a First name")

        user = self.model(
            email=self.normalize_email(email),
            first_name=first_name,
            last_name=last_name,
            department=department,
        )
        user.set_password(password)
        user.is_staff = True
        user.is_admin = True
        user.is_superadmin = True
        user.is_active = True
        user.save(using=self._db)
        return user

  • admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

# Register your models here.
from .models import Account


class AccountAdmin(UserAdmin):
    list_display = ("email", "first_name", "department", "date_joined")
    filter_horizontal = ()
    list_filter = ()
    fieldsets = ()  # this will make the password in the admin page read-only
    ordering = ["roll_number"]


admin.site.register(Account, AccountAdmin)

When i create a superuser i am getting this error :

> python manage.py createsuperuser
Email: [email protected]
First name: test2
Last name: test
Department: OTHER
Password: 
Password (again): 
Traceback (most recent call last):
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: accounts_account.roll_number

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/dhruv/Desktop/hire-them/manage.py", line 22, in <module>
    main()
  File "/home/dhruv/Desktop/hire-them/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 88, in execute
    return super().execute(*args, **options)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 233, in handle
    self.UserModel._default_manager.db_manager(database).create_superuser(
  File "/home/dhruv/Desktop/hire-them/accounts/manager.py", line 43, in create_superuser
    user.save(using=self._db)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/contrib/auth/base_user.py", line 68, in save
    super().save(*args, **kwargs)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 831, in save
    self.save_base(
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 882, in save_base
    updated = self._save_table(
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 1025, in _save_table
    results = self._do_insert(
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 1066, in _do_insert
    return manager._insert(
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 1790, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1657, in execute_sql
    cursor.execute(sql, params)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 103, in execute
    return super().execute(sql, params)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/home/dhruv/Desktop/hire-them/.venv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_account.roll_number

CodePudding user response:

You can make the roll_no nullable:

class Account(AbstractBaseUser):
    # …
    roll_number = models.CharField(max_length=10, null=True, unique=True)

and then use NULL in the create_superuser:

def create_superuser(
    self, email, first_name, last_name, password, department="OTHER"
):
    if not email:
        raise ValueError("Admin requires an Email")
    if not first_name:
        raise ValueError("Admin requires a First name")

    user = self.model(
        email=self.normalize_email(email),
        first_name=first_name,
        last_name=last_name,
        department=department,
        is_staff=True,
        is_admin=True,
        is_superadmin=True,
        is_active=True,
        roll_number=None,
    )
    user.set_password(password)
    user.save(using=self._db)
    return user

CodePudding user response:

Since roll_number is neither nullable nor blankable as well as it is unique. Thus we have to pass it to create a user. In create_superuser function, you can set negative integers as roll_number. Fetch all the objects with roll_number negative at find the least roll_number, subtract 1 and pass it to user. Or you can choose sequence which should never clash with any other user.

  • Related