Home > Blockchain >  Django pass id from one model to another's foreign key
Django pass id from one model to another's foreign key

Time:09-28

I have a User model and Employee model which stands for additional info about user, it has one to one field relation with User instance. When new User is created I use signals to create new Employee instance. Now I added new field to User model called 'fk_employee_id' just to have a link to this newly created Employee and I'm not sure how to do pass it's id to this User's fk field. I tried to write in my signals something like instance.user.fk_employee_id = sender after that I get

ValueError Cannot assign "<class 'employees.models.Employees'>": "User.fk_employee_id" must be a "Employees" instance.

So how do I fill this foreign key field in User instance when Employee is created?

My User model:

class User(AbstractBaseUser):
    email = models.EmailField(verbose_name='email', max_length=60, unique=True)
    username = models.CharField(max_length=30, unique=True, validators=[validate_username])
    date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=50)
    fk_employee_id = models.OneToOneField('employees.Employees', related_name='fk_employee_id',
                                          null=True,on_delete=models.DO_NOTHING)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'first_name', 'last_name']

    objects = UserManager()

The Employee model is large, it has basic fields like number, address etc. Nothing special.

My signals file in users app:

from django.db.models.signals import post_save
from .models import User
from django.dispatch import receiver
from employees.models import Employees


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Employees.objects.create(user=instance, first_name=instance.first_name,
                                 last_name=instance.last_name)


@receiver(post_save, sender=Employees)
def save_profile(sender, instance,  **kwargs):
    instance.user.save()

CodePudding user response:

You don't need 2 OneToOneFields. One for the Employee is enough.

Let's say you have:

class Employee(models.Model):
    user = models.OneToOneField(User, related_name='employee_profile',on_delete=models.DO_NOTHING)
    ...

After migration, you can just call user.employee_profile (like in the related_name attribute).

  • Related