Обход разрешений 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
)
Это позволит использовать JOIN
s вместо … IN …
с подзапросами, которые имеют тенденцию быть менее эффективными, особенно в MySQL.