Поле OnetoMany в моделях django

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

a UserRank class, который я могу определить как угодно много рангов, например (капитан, 2-й инженер, старший помощник... и т.д.) User class, который может иметь одно из вышеперечисленных званий, job class, который может иметь 1 или много рангов из UserRank class

models.py

class UserRank(models.Model):
    rank = models.CharField(blank=True,null=True,max_length=150)
   

    def __str__(self):
        return self.rank


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=150,unique=True)
    name = models.CharField(max_length=150,)
    phone = models.CharField(max_length=50)
    date_of_birth = models.DateField(blank=True, null=True)
    picture = models.ImageField(blank=True, null=True, upload_to='users_imgs')
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(default=timezone.now)
    last_login = models.DateTimeField(null=True)
    user_rank = models.ForeignKey(UserRank,related_name='userRank',null=True,on_delete=models.SET_NULL)
    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email','name']

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username.split()[0]

class Job(models.Model):
    job_type = (
        ('I', 'Interval'),
        ('O', 'One time'),
    )
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=100)
    type = models.CharField(max_length=1, choices=job_type)
    interval = models.IntegerField()
    is_critical = models.BooleanField()
    due_date = models.DateField()
    user_rank = models.ManyToManyField(UserRank,related_name='ranks',blank=True)
    component = models.ForeignKey(
        Component, related_name='jobs', on_delete=models.CASCADE)
    runninghours = models.ForeignKey(
        RunningHours, related_name="RHjobs", on_delete=models.CASCADE)   

    def __str__(self):
        return self.name

Вероятно, вы ищете "обратное отношение" отношения ForeignKey. Посмотрите документацию Django: Следование отношений в обратном направлении

(Резюме: Entry имеет внешний ключ к Blog, и по умолчанию Blog.entry_set является менеджером для связанных Entry объектов, например Blog.entry_set.all() или любого более сложного Queryset для их фильтрации. Имя entry_set является именем по умолчанию, вы можете изменить его через related_name на ForeignKey в Entry)

В отношениях один-ко-многим, "дочерний" экземпляр содержит первичный ключ родительского экземпляра в качестве внешнего ключа.

Это означает, что если у вас есть связь между UserRank и Job, каждый Job instance будет иметь атрибут типа ForeignKey, содержащий первичный ключ родителя Job instance.

# Setup 
class UserRank(models.Model):
    ...attributes

class Job(models.Model):
    user_rank = models.ForeignKey(UserRank, on_delete=models.CASCADE, related_name="jobs")

# Accessing jobs from UserRank
user_rank_1 = UserRank.objects.create(...)

# There is one UserRank instance with many child job instances, so we have to cycle through them
for job in user_rank_1.jobs.all():
   print(job)

# Result
# >>> job1
# >>> job2
# >>> job3

# Accessing UserRank from a Job instance
job = Job.objects.get(id=1)

# Every job instance only has one parent UserRank, so it's sufficient to reference it directly with the dot notation
print(job.user_rank)

# Result
# >>> user_rank_1


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