Django: проверить, последний ли объект был связан один с другим - PullRequest
1 голос
/ 25 февраля 2020

Я пишу функцию удаления в django (python).
Мне нужно удалить сайт. Сайт может быть связан с несколькими группами.
Прежде чем сайт можно будет удалить, я должен проверить, является ли сайт последним сайтом из группы.
Я думаю о том, как сделать это наиболее эффективно.
Должен ли я запрашивать все сайты для всех групп, с которыми связан сайт, прежде чем удалять сайт и проверять, является ли сайт единственным связанным?

    site = get_object_or_404(Site, pk=site_pk)
    group = Group.objects.prefetch_related("user_site").filter(
        user_site__site_id=site_pk
    )

    site.delete()

Модель сайта: - никаких отношений, только базовые c атрибуты

Модель группы:

имеет имя и

def get_linked_sites(self):
    user_sites = self.usersites.all()
    return [usersite.usersite.site.id for usersite in user_sites]

Модель UserSite:

user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="sites")
site = models.ForeignKey(Site, on_delete=models.CASCADE, related_name="users")
group = models.ForeignKey(
    Group,
    on_delete=models.SET_NULL,
    related_name="user_site",
    default=None,
    blank=True,
    null=True,
)

UserSiteGroup модель:

 usersite = models.ForeignKey(
        UserSite, on_delete=models.CASCADE, related_name="groups"
    )
    group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name="usersites")

Решение (но может быть лучше?):

    site = get_object_or_404(Site, pk=site_pk)

    groups = (
        Group.objects.filter(usersites__usersite__site_id=site_pk)
        .prefetch_related("usersites__usersite")
        .distinct()
        .all()
    )

    for group in groups:
        if len(group.get_linked_sites()) > 1:
            group.delete()

    site.delete()

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Вы можете использовать следующий код:

group = Group.objects.get(pk=site.group_id)
if group.site_set.exclude(pk=site.id).count == 0:
    site.delete()
    group.delete()
0 голосов
/ 25 февраля 2020

Я предполагаю, что ваше определение группы имеет внешний ключ сайта? Если это так, вы можете добавить или использовать связанное имя, например,

class Group(models.Model):
    ...
    site = models.ForeignKey(Group, on_delete=models.CASCADE, related_name="groups")

Затем вы можете просто проверить с помощью

if not user_site.groups.all().exists():
    user_site.delete()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...