Создание пользовательской модели пользователя и профиля
Я пытаюсь создать форму добавления пользователя из фронтенда, которая создает пользователя и дополнительную информацию на основе пользовательской модели пользователя.Но я получаю 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
1from 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')