I am building a web API in Django and DRF. I have an Artist model that contains different fields and a OneToOnefield
to a user which was inherited from an AbstractBaseUser
class that contains the following fields: username
, email
, first_name
, last_name
, is_artist
. I want a situation whereby once a user is created, an instance of the Artist model is also created.
Note: I am handling authentication endpoints using Third-Party packages and libraries using Djoser. So I didn't define any views for the user model.
How can I achieve what I have described above?
Here's my code:
The User model:
import uuid
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class User(AbstractBaseUser, PermissionsMixin):
pkid = models.BigAutoField(primary_key=True, editable=False)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
username = models.CharField(verbose_name=_("Username"), max_length=255, unique=True)
first_name = models.CharField(verbose_name=_("First Name"), max_length=50)
last_name = models.CharField(verbose_name=_("Last Name"), max_length=50)
email = models.EmailField(verbose_name=_("Email Address"), unique=True)
is_artist = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "first_name", "last_name", "is_artist"]
objects = CustomUserManager()
class Meta:
verbose_name = _("User")
verbose_name_plural = _("Users")
def __str__(self):
return self.username
@property
def get_full_name(self):
return f"{self.first_name} {self.last_name}"
def get_short_name(self):
return self.username
The Artist model:
from django.contrib.auth import get_user_model
from django.db import models
from django.utils.translation import gettext_lazy as _
from django_countries.fields import CountryField
from phonenumber_field.modelfields import PhoneNumberField
from common.models import TimeStampedUUIDModel
User = get_user_model()
class Gender(models.TextChoices):
MALE = "Male", _("Male")
FEMALE = "Female", _("Female")
OTHER = "Other", _("Other")
class Artist(TimeStampedUUIDModel):
user = models.OneToOneField(User, related_name="artist", on_delete=models.CASCADE)
stage_name = models.CharField(verbose_name=_("Stage Name"), max_length=255, unique=True)
gender = models.CharField(verbose_name=_("Gender"), choices=Gender.choices, default=Gender.OTHER, max_length=20)
phone_number = PhoneNumberField(verbose_name=_("Phone Number"), max_length=30, default="+2348037286666", unique=True)
bio = models.CharField(verbose_name=_("Bio"), max_length=255, blank=True, null=True)
music_class = models.CharField(verbose_name=_("Music Class"), max_length=255, blank=True)
company_name = models.CharField(verbose_name=_("Company Name"), max_length=55, blank=True)
sor = models.CharField(verbose_name=_("State of Residence"), max_length=255, blank=True)
lga = models.CharField(verbose_name=_("Local Government Area"), max_length=225, blank=True, null=True)
address = models.CharField(verbose_name=_("Address"), blank=True, max_length=225)
postal_code = models.CharField(verbose_name=_("Postal Code"), blank=True, null=True, max_length=8)
country = CountryField(verbose_name=_("Country"), default="NG", blank=True, null=True)
country_code = models.CharField(verbose_name=_('Country Code'), default="NG", blank=True, max_length=5)
state = models.CharField(verbose_name=_("State"), max_length=25, null=True, blank=True)
city = models.CharField(verbose_name=_("city"), max_length=75, null=True, blank=True)
dob = models.DateField(verbose_name=_("Date of Birth"), null=True)
def __str__(self):
return f"{self.user.username}'s profile"
The simplest way is to extend the save function of your User