Профиль не зарегистрирован у автоматически созданного пользователя через сигналы

У меня есть приложение django, в котором следующая модель с именем Employee играет роль пользователя Profile, которая связана с User из модуля auth:

class Employee(models.Model):

    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField(unique=True)
    phone = models.IntegerField(blank=True)
    is_chef_de_project = models.BooleanField(
        default=False
    )
    is_chef_de_produit = models.BooleanField(
        default=False
    )
    is_ghr = models.BooleanField(
        default=False
    )

    account = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        null=True
    )

я хочу автоматически создавать User при регистрации Employee, поэтому я создал следующий файл signals.py:

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.contrib.auth import hashers
from django.dispatch import receiver
from .models import Employee


def generate_password():
    import secrets
    import string
    alphabet = string.ascii_letters + string.digits
    return ''.join(secrets.choice(alphabet) for i in range(10))


@receiver(post_save, sender=Employee)
def create_user(sender, instance, created, **kwargs):
    breakpoint()
    if created:
        uname = instance.first_name[0].lower() + instance.last_name.lower()
        passd = generate_password()
        User.objects.create(employee=instance, username=uname, password=passd)
        print("generated credentials:" + uname + ":" + passd)


@receiver(post_save, sender=Employee)
def save_user(sender, instance, **kwargs):
    breakpoint()
    instance.account.save()

но после регистрации я обнаружил, что атрибут account в созданном экземпляре Employee null:

null account

есть намеки на то, что происходит?

я ожидал, что на созданный экземпляр User будет ссылаться зарегистрированный Employee

Забавно, User имеет атрибут employee, но в базе данных отношение хранится в модели Employee.

В вашем случае:

@receiver(post_save, sender=Employee)
def create_user(sender, instance, created, **kwargs):
    if not instance.account_id:  # o2o is empty
        uname = instance.first_name[0].lower() + instance.last_name.lower()
        passd = generate_password()
        instance.account = User.objects.create(username=uname, password=passd)
        print("generated credentials:" + uname + ":" + passd)
        instance.save()  # recursive signal, but account_id should be not more empty

Мое мнение, логика здесь немного нарушена, потому что вы используете сигналы, а это само по себе плохая практика. Но это должно работать.

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