Запрашивать поле модели только при создании пользователя, но не суперпользователя. (Django)
Я делаю студенту колледжа приложение Django для связи.
Вопрос : Я хотел, чтобы мое приложение Django не запрашивало "roll_number" при создании суперпользователя, чего оно не делает, но я все равно получаю эту ошибку (ошибка внизу), и я не могу сделать его null или пустым, потому что я хочу, чтобы он запрашивался в форме Django для регистрации студентов. Как мне это сделать?
Код :
- 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)
Когда я создаю суперпользователя, я получаю эту ошибку :
Поскольку roll_number
не является ни nullable, ни blankable, а также уникальным. Таким образом, мы должны передать его для создания пользователя. В функции create_superuser
можно задавать отрицательные целые числа как roll_number
. Перебрать все objects
с отрицательными roll_number
, найти наименьшее roll_number
, вычесть 1 и передать его пользователю. Или вы можете выбрать последовательность, которая никогда не должна конфликтовать с любым другим пользователем.
Вы можете сделать roll_no
nullable:
class Account(AbstractBaseUser):
# …
roll_number = models.CharField(max_length=10, null=True, unique=True)
и затем используйте NULL
в 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