Используйте пользовательский запрос соединения с отношением Django ManyToMany

#python #django

#python #django

Вопрос:

У меня есть User модель, которая подключается к Role модели через ManyToMany, а затем Role модель подключается к двум моделям, SitePermission или ForumPermission . Проблема в том, что я не могу понять, как настроить это соединение.

Вот мои модели, с удаленными (я полагаю) нерелевантными полями.

Роль:

 class Role():
    class RoleTypes(models.TextChoices):
        SITE = "s", "Site"
        FORUM = "f", "Forum"

    role_type = models.CharField(max_length=1, choices=RoleTypes.choices, null=True)
    permissions = models.ManyToManyField(
        "permissions.Permission",
        related_name="roles",
        through="permissions.RolePermissions",
    )
 

Ролевые разрешения:

 class RolePermissions():
    role = models.ForeignKey("permissions.Role", on_delete=models.PROTECT)
    permission = models.ForeignKey("permissions.SitePermission", on_delete=models.PROTECT)
 

SitePermissions:

 class SitePermissions():
    permission = models.CharField(max_length=64)
 

ForumPermissions:

 class SitePermissions():
    permission = models.CharField(max_length=64)
    forum = models.ForeignKey(
        "forums.forum", db_column="forumId", on_delete=models.PROTECT
    )
 

Проблема, конечно, в том, что я не могу подключить несколько таблиц к ManyToMany. Если бы я делал это в SQL, у меня было бы что-то вроде roles r LEFT JOIN role_permissions rp_s ON r.type = 's' and r.id = rp.role_id INNER JOIN site_permissions sp ON rp_s.permission_id = sp.id второго набора соединений для forum_permissions (я знаю, что SQL не совсем правильный, например, more).

Итак, есть ли способ добиться этого? Условная ссылка на несколько таблиц? Или мне нужно иметь отдельное свойство Role для каждого SitePermission и ForumPermission , а затем иметь логику для каждого, чтобы использовать его?

Ответ №1:

попробуйте

 RolePermissions.objects.raw("roles r LEFT JOIN role_permissions rp_s ON r.type = 's' and r.id = rp.role_id INNER JOIN site_permissions sp ON rp_s.permission_id = sp.id")
 

Комментарии:

1. Хех, так что я знаю, что могу использовать необработанный синтаксис, мне было более любопытно, есть ли способ Django сделать это.

2. Я думаю, что нет. ДО сих пор я тоже не нашел способа. Я пришел из RoR, и я немного разочарован тем, что для этого нет «способа Django». Ну что ж … может быть, когда я немного освоюсь с Python и Django, я сделаю PR : -p