I want to apply CSS style in the form class inherited UserCreationForm
.
I tried to set attribute in widgets
under class Meta
, but only password1
and password2
field didn’t work.
So I use the code below under def __init__
, and it worked.
self.fields["password1"].widget.attrs["class"] = "form-control"
self.fields["password2"].widget.attrs["class"] = "form-control"
I think it’s because there is no password1
and password2
field in models.py
My question is these.
- Is my thought right? (Style didn’t applied because there are no
password1
andpassword2
inmodels.py
) - Is that the only way to apply style on those fields?
For your information, here are my models.py
and forms.py
models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, Group
from django.core.validators import RegexValidator
from django.db import models
from django.urls import reverse
from django.utils import timezone
from branches.models import Branch
# Create your models here.
phone_validator = RegexValidator(
regex="\d{2,4}-?\d{3,4}(-?\d{4})?",
message="This is not correct phone number format",
)
class UserManager(BaseUserManager):
def create_user(
self,
username,
full_name,
birthday,
gender,
phone,
branch,
password=None,
**kwargs,
):
user = self.model(
username=username,
full_name=full_name,
group=Group.objects.get_or_create(name="Members"),
birthday=birthday,
gender=gender,
phone=phone,
license_type=kwargs["license_type"],
plan_type=kwargs["plan_type"],
branch=Branch.objects.get(srl=branch),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_staff(
self, username, full_name, birthday, gender, phone, branch, password, **kwargs
):
user = self.create_user(
username, full_name, birthday, gender, phone, branch, password, kwargs
)
user.staff = True
user.group = (Group.objects.get_or_create(name="Staffs"),)
user.save(using=self._db)
return user
def create_superuser(
self, username, full_name, birthday, gender, phone, branch, password, **kwargs
):
user = self.create_user(
username, full_name, birthday, gender, phone, branch, password, kwargs
)
user.staff = True
user.superuser = True
user.group = (Group.objects.get_or_create(name="Superusers"),)
user.save(using=self._db)
return user
class User(AbstractBaseUser):
objects = UserManager()
GENDERS = (
(None, "Not Chosen"),
("M", "Male"),
("F", "Female"),
)
LICENSE_TYPES = (
(None, "Not Chosen"),
("1L", "Class 1 Large"),
("1O", "Class 1 Ordinary"),
("1OA", "Class 1 Ordinary (Automatic)"),
("2O", "Class 2 Ordinary"),
("2OA", "Class 2 Ordinary (Automatic)"),
("P", "Practice"),
)
PLAN_TYPES = (
(None, "Not Chosen"),
("T", "Time-based"),
("G", "Guarantee"),
("P", "Practice"),
)
srl = models.BigAutoField(
primary_key=True,
verbose_name="Serial",
)
username = models.TextField(
unique=True,
verbose_name="Username",
)
full_name = models.TextField(
verbose_name="Full name",
)
password = models.TextField(
verbose_name="Password",
)
groups = models.ManyToManyField(
to=Group,
verbose_name="Group",
)
birthday = models.DateField(
verbose_name="Birthday",
)
gender = models.TextField(
verbose_name="Gender",
choices=GENDERS,
)
phone = models.TextField(
verbose_name="Phone number",
validators=(phone_validator,),
)
branch = models.ForeignKey(
"branches.Branch",
verbose_name="Branch",
on_delete=models.DO_NOTHING,
)
license_type = models.CharField(
max_length=3,
verbose_name="License type",
choices=LICENSE_TYPES,
blank=True,
null=True,
default=None,
)
plan_type = models.CharField(
max_length=1,
verbose_name="Plan type",
choices=PLAN_TYPES,
blank=True,
null=True,
default=None,
)
staff = models.BooleanField(
verbose_name="Staff",
default=False,
)
active = models.BooleanField(
verbose_name="Active",
default=True,
)
superuser = models.BooleanField(
verbose_name="Superuser",
default=False,
)
last_login = models.DateTimeField(
verbose_name="Last login",
default=timezone.now,
)
date_joined = models.DateTimeField(
verbose_name="Date joined",
default=timezone.now,
)
USERNAME_FIELD = "username"
REQUIRED_FIELDS = (
"name",
"birthday",
"gender",
"phone",
"branch",
)
@property
def is_staff(self):
return self.staff
@property
def is_active(self):
return self.active
@property
def is_superuser(self):
return self.superuser
def has_perm(self, perm, obj=None):
return self.staff
def has_module_perms(self, app_label):
return self.staff
class Meta:
verbose_name = "User"
verbose_name_plural = "Users"
ordering = [
"branch",
"srl",
]
def __str__(self):
if self.gender == "M":
gender_short = "M"
elif self.gender == "F":
gender_short = "F"
return f"{self.full_name} ({self.branch}/{self.birthday.strftime('%y%m%d')}/{gender_short})"
def get_absolute_url(self):
return reverse("users:detail", kwargs={"srl": self.srl})
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError
from django.forms import ModelChoiceField
from branches.models import Branch
from users.models import User
class UserForm(UserCreationForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super(UserForm, self).__init__(*args, **kwargs)
# These work well
self.fields["password1"].widget.attrs["class"] = "form-control"
self.fields["password2"].widget.attrs["class"] = "form-control"
if self.user.is_superuser:
self.fields["branch"] = ModelChoiceField(
queryset=Branch.objects.all(),
required=True,
label="Branch",
widget=forms.Select(
attrs={
"class": "form-select",
},
),
)
self.fields["groups"] = ModelChoiceField(
queryset=Group.objects.all(),
required=True,
label="Group",
widget=forms.Select(
attrs={
"class": "form-select",
},
),
)
else:
self.fields["branch"] = ModelChoiceField(
queryset=Branch.objects.filter(branch=self.user.branch),
required=True,
label="Branch",
widget=forms.Select(
attrs={
"class": "form-select",
}
),
)
self.fields["groups"] = ModelChoiceField(
queryset=Group.objects.filter(name__in=["Member", "Staff"]),
required=True,
label="Group",
widget=forms.Select(
attrs={
"class": "form-select",
},
),
)
def clean_phone(self):
phone_number = self.cleaned_data["phone"]
phone_number = phone_number.replace("-", "")
if len(phone_number) == 0:
return phone_number
elif phone_number[0:2] == "02" and len(phone_number) == 9:
phone_number = [phone_number[0:2], phone_number[2:5], phone_number[5:]]
phone_number = "-".join(phone_number)
elif phone_number[0:2] == "02" and len(phone_number) == 10:
phone_number = [phone_number[0:2], phone_number[2:6], phone_number[6:]]
phone_number = "-".join(phone_number)
elif phone_number[0] != 0 and len(phone_number) == 8:
phone_number = [phone_number[0:4], phone_number[4:]]
phone_number = "-".join(phone_number)
elif len(phone_number) == 10:
phone_number = [phone_number[0:3], phone_number[3:6], phone_number[6:]]
phone_number = "-".join(phone_number)
elif len(phone_number) == 11:
phone_number = [phone_number[0:3], phone_number[3:7], phone_number[7:]]
phone_number = "-".join(phone_number)
return phone_number
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise ValidationError("Passwords are not matched.")
return password2
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class Meta:
model = User
fields = (
"username",
"full_name",
"password1",
"password2",
"groups",
"birthday",
"gender",
"phone",
"branch",
"license_type",
"plan_type",
)
widgets = {
"username": forms.TextInput(
attrs={
"class": "form-control",
}
),
"full_name": forms.TextInput(
attrs={
"class": "form-control",
}
),
# These don't work
# "password1": forms.PasswordInput(
# attrs={
# "class": "form-control",
# }
# ),
# "password2": forms.PasswordInput(
# attrs={
# "class": "form-control",
# }
# ),
"birthday": forms.DateInput(
attrs={
"type": "date",
"class": "form-control",
}
),
"gender": forms.RadioSelect(
attrs={
"class": "form-check-input",
},
),
"phone": forms.TextInput(
attrs={
"type": "tel",
"class": "form-control",
},
),
"license_type": forms.Select(
attrs={
"class": "form-select",
},
),
"plan_type": forms.Select(
attrs={
"class": "form-select",
},
),
"staff": forms.RadioSelect(
choices=[(True, "Yes"), (False, "No")],
attrs={
"class": "form-check-input",
},
),
}