Создание пользовательской модели пользователя и профиля

Я пытаюсь создать форму добавления пользователя из фронтенда, которая создает пользователя и дополнительную информацию на основе пользовательской модели пользователя.Но я получаю duplicate key value violates unique constraint "users_driver_email_key" DETAIL: Key (email)=() already exists. вот мой код:

Models.py

class CustomUser(AbstractUser):
    is_driver = models.BooleanField(default=False)
    is_accountant = models.BooleanField(default=False)
    is_dispatcher = models.BooleanField(default=False)



class Driver(models.Model):
    driver_user = models.OneToOneField(CustomUser, on_delete = models.CASCADE, primary_key = True)
    full_name = models.CharField(max_length=50, default=None)
    
    date_created = models.DateTimeField(auto_now_add=True)
    date_edited = models.DateTimeField(auto_now=True)
    status = models.IntegerField(choices=STATUS, default=1)

        
class DriversFiles(models.Model):
    file = models.FileField(upload_to="media/", blank=True, null=True)
    driver_files = models.ForeignKey('Driver', on_delete=models.CASCADE, default=None, null=True)

@receiver(post_save, sender=CustomUser)
def create_user_profile(sender, instance, created, **kwargs):
# if Created is true (Means Data Inserted)
if created:
    # Check the user_type and insert the data in respective tables
    if instance.is_driver:
        Driver.objects.create(
            driver_user=instance, 
            full_name = "123",
            phone_number = "123",
            email = "",
            address = "123",
            country = "123",
            state = "123",
            city = "123",
            zipp = "213",
            birth_date = '2022-01-01',
            license_no = '1234',
            license_exp_date = '2022-01-01',
            last_medical= '2022-01-01',
            next_medical = '2022-01-01',
            last_drug_test = '2022-01-01',
            next_drug_test = '2022-01-01',
            )

Views.py

def create_driver_view(request):
    if request.method == "POST":
        add_driver = DriverForm(request.POST)
        add_driver_file = request.FILES.getlist("file")
        
        if add_driver.is_valid():
            #For Custom User
            password = 'Ga20224$5%'
            full_name = add_driver.cleaned_data['full_name']
            email = add_driver.cleaned_data['email']
            phone_number = add_driver.cleaned_data['phone_number']
            address = add_driver.cleaned_data['address']
            country = add_driver.cleaned_data['country']
            state = add_driver.cleaned_data['state']
            city = add_driver.cleaned_data['city']
            zipp = add_driver.cleaned_data['zipp']
            birth_date = add_driver.cleaned_data['birth_date']
            license_no = add_driver.cleaned_data['license_no']
            
            license_exp_date = add_driver.cleaned_data['license_exp_date']
            last_medical = add_driver.cleaned_data['last_medical']
            next_medical = add_driver.cleaned_data['next_medical']
            last_drug_test = add_driver.cleaned_data['last_drug_test']
            next_drug_test = add_driver.cleaned_data['next_drug_test']
            print(email)
            username = email.split('@')[0] + uuid.uuid4().hex[:2]
            user = CustomUser.objects.create_user(
                username = username, 
                password = password, 
                is_driver = True, 
                email = email
                )
            
            #For Driver Profile
            user.driver.full_name = full_name
            user.driver.email = email
            user.save()
            # for i in add_driver_file:
            #     DriversFiles.objects.create(driver_files=user, file=i)
            return redirect('drivers:list_driver')  
        else:
            print(add_driver.errors)
            
    else:
        add_driver = DriverForm()
        add_driver_files = DriverFormUpload()

    return render(request, "drivers/add.html", {"add_driver": add_driver, "add_driver_files": add_driver_files})

Я получал ошибку {{message}}, что имя пользователя или email уже заняты, но теперь он открывает отладчик. Кроме того, он создает учетные записи пользователей с одинаковыми email'ами, но затем не создает таблицу Driver, потому что email не уникален.

Я новичок в django и просто хотел создать пользовательские модели пользователей, но есть так много головной боли. Что мне делать. или как мне правильно создать пользовательские модели пользователей

Поскольку вы наследуете от класса AbstractUser ( см. строку 334), у вас уже есть поле email в экземпляре пользователя. Таким образом, удаление поля email из модели драйвера должно решить вашу проблему.

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.
    Username and password are required. Other fields are optional.
    """

    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _("username"),
        max_length=150,
        unique=True,
        help_text=_(
            "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
        ),
        validators=[username_validator],
        error_messages={
            "unique": _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_("first name"), max_length=150, blank=True)
    last_name = models.CharField(_("last name"), max_length=150, blank=True)
    email = models.EmailField(_("email address"), blank=True)

Если вы хотите использовать поле email в качестве auth и unique, вы можете сделать это следующим образом:

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

from .managers import CustomUserManager


class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        return self.email

Django предоставил средства для настройки модели USER по умолчанию.

Имеют два знаменитых подхода...

1 - Расширение модели пользователя с помощью пользовательской модели Расширение AbstractUser

1
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)
    profile_pic = models.ImageField(upload_to ='/Propife/',null=True, blank=True)

2 - Расширение модели пользователя с помощью пользовательской модели Расширение AbstractBaseUser

from django.db import models
from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import ugettext_lazy as _

from .managers import UserManager


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
    is_active = models.BooleanField(_('active'), default=True)
    profile_pic = models.ImageField(upload_to ='/Propife/',null=True, blank=True)
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

NOTE:- поместите все поля с null=True blank=True, которые вы хотите использовать для профиля. и создайте форму с CustomUserModel, а затем напишите функциональность обновления для полей профиля, которые оставьте с null=True blank=True.

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