Обход разрешений Django по нескольким внешним ключам

У меня есть 4 основные модели сущностей:

  • Пользователь
    • Может быть владельцем или участником коллекции
  • Коллекция
  • Рецепт
    • Рецепт имеет внешний ключ к коллекции
  • Шаги
    • Шаг имеет внешний ключ к рецепту

Для того, чтобы включить все вышеперечисленное, я думаю, мне нужна модель для каждого из них, а также модель (назовем ее CollectionContributor) со следующими полями:

  • contributor - это будет внешний ключ к модели пользователя
  • collection - это будет внешний ключ к коллекции

В Коллекции я бы добавил поле "многие ко многим", которое выглядит следующим образом:

class Collection(models.Model):
    ...
    contributors = models.ManyToManyField(settings.AUTH_USER_MODEL, through='CollectionContributor')

Допустим, я хочу предоставить страницу, на которой перечислены все "шаги" по всем рецептам. Если я хочу ограничить это представление только теми шагами, которые являются частью рецептов, входящих в коллекции, к которым у пользователя есть доступ, как мне это сделать. По сути, как я могу управлять разрешениями, которые требуют обхода нескольких внешних ключей?

Я предположил, что это может быть что-то вроде следующего. Но это кажется ужасно неэффективным и может привести к проблемам с производительностью, если сущности уходят на несколько слоев вглубь. Является ли это "правильным" способом?

def someViewOfSteps(request):
    collections = models.Collection.objects.filter(Q(contributors__in=request.user))
    recipes = models.Recipe.objects.filter(Q(collection__in=collections))
    steps = models.Step.objects.filter(Q(recipe__in==recipe))
    return steps

Правильно ли это?

Вы можете сделать запрос с помощью:

def someViewOfSteps(request):
    return Step.objects.filter(
        recipe__collection__contributors=request.user
    )

Это позволит использовать JOINs вместо … IN … с подзапросами, которые имеют тенденцию быть менее эффективными, особенно в MySQL.

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