Кверисет для объединения нескольких таблиц
class Organization(models.Model):
"""Organization Model"""
name = models.CharField(max_length=100, blank=False)
is_active = models.BooleanField(default=True)
class Department(models.Model):
"""Department Model"""
org = models.ForeignKey(Organization, on_delete=models.PROTECT, related_name='Department_Org')
name = models.CharField(max_length=100, blank=False)
is_active = models.BooleanField(default=True)
class Project(models.Model):
"""Project Model"""
dept = models.ForeignKey(Department, on_delete=models.PROTECT, related_name='Project_Dept', null=True)
no = models.CharField(max_length=100, blank=False)
name = models.CharField(max_length=255, blank=True)
is_active = models.BooleanField(default=True)
class Subscription(models.Model):
"""Subscription Model"""
MODULE_CHOICES = (
('ECM', 'Change Management'),
('DMS', 'Document Management'),
('AIM', 'Deviation Management'),
('PMS', 'Project Management'),
('ADM', 'Admin'),
('RPT', 'Reports'),
('MTS', 'My Tasks'),
)
project = models.ForeignKey(Project, on_delete=models.PROTECT, related_name='Subscription_Project')
module = models.CharField(max_length=3, choices=MODULE_CHOICES)
class User(AbstractBaseUser, PermissionsMixin):
"""Custom User Model"""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
displayname = models.CharField(max_length=255, blank=True)
fname = models.CharField(max_length=255, blank=True)
lname = models.CharField(max_length=255, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
class UserProjectSubscriptionRole(models.Model):
"""User Role Model"""
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='UserProjectRole_user')
project = models.ForeignKey(Subscription, on_delete=models.PROTECT, related_name='UserProjectRole_Module')
role = models.ForeignKey(RoleType, on_delete=models.PROTECT, related_name="UserProjectRole_role")
Мне нужно написать набор запросов для получения организаций, с которыми связан пользователь.
Вы можете фильтровать с помощью:
Organization.objects.filter(
Department_Org__Project_Dept__UserProjectRole_Module__user=my_user
)
Однако значения related_name=… [Django-doc] громоздки: это имена для доступа к связанным объектам, которые указывают на объект. Ваш UserProjectSubscriptionRole также является моделью перехода ManyToManyField. Вы можете переписать моделирование на:
class Department(models.Model):
org = models.ForeignKey(Organization, on_delete=models.PROTECT, related_name='departments')
# …
class Project(models.Model):
dept = models.ForeignKey(Department, on_delete=models.PROTECT, related_name='projects', null=True)
# …
class Subscription(models.Model):
project = models.ForeignKey(Project, on_delete=models.PROTECT, related_name='subscriptions')
# …
class User(AbstractBaseUser, PermissionsMixin):
# …
projects = models.ManyToManyField(
Project,
trough='UserProjectSubscriptionRole',
related_name='users'
)
class UserProjectSubscriptionRole(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='userprojectroles')
project = models.ForeignKey(Subscription, on_delete=models.PROTECT, related_name='userprojectroles')
role = models.ForeignKey(RoleType, on_delete=models.PROTECT, related_name='userprojectroles')
Затем вы можете фильтровать с помощью:
Organization.objects.filter(
departments__projects__users=my_user
)
Это кажется более читабельным и компактным.