Я пытаюсь сделать так, чтобы только те люди, которые будут присутствовать на мероприятии, могли просматривать только те мероприятия, на которых они присутствуют. Как мне это сделать?
Я использую Django для целей этого проекта, и у меня есть отношение "многие-ко-многим" между человеком и событием (многие люди могут быть на многих [существующих] событиях), и я хочу убедиться, что каждый человек может просматривать только те события, на которых он присутствует, а не любые другие.
Я пытаюсь сделать это через панель администратора с помощью has_view_permission
, но не имею ни малейшего представления о том, как это сделать. Я пытаюсь использовать request.user
для целей этой проверки.
Я знаю, что использование сквозной таблицы с models.ForeignKey
также работает, но поскольку в Django уже есть такая реализация, невидимая для конечного пользователя, я хотел попробовать эту идею с models.ManyToManyField
.
На данный момент у меня есть вот что для models.py
:
class Person(models.Model):
# fields in the model such as id, name, etc.
class Event(models.Model):
# fields similar to Person - id, name, date, etc.
attendees = models.ManyToManyField(Person)
и для admin.py
from django.contrib import admin
from .models import Person, Event
class EventAdmin(admin.ModelAdmin):
def has_view_permission(self, request, obj=None):
if Event.objects.filter(attendees = request.user):
return True
else:
return False
Однако, как можно предположить, это не позволяет никому, кроме людей, участвующих в событиях, просматривать эти события, что дает мне ValueError
в панели администратора. Обратите внимание, что я добавил персону и событие перед перегрузкой функции.
При открытии страницы администратора я получаю
Cannot query "admin": Must be "Person" instance.
, что нежелательно.
Теперь у меня такой вопрос: как сделать так, чтобы люди (посетители) могли просматривать только те события, в которых они участвуют, не мешая остальным просматривать что-либо?
Если это можно сделать более элегантным способом без has_view_permission
, то я не против использовать и этот метод.
Метод has_view_permission
используется как в представлении списка, так и в представлении деталей. В представлении списка obj - это None, а в представлении детализации он представляет собой экземпляр события.
Чтобы убедиться, что обычные пользователи могут получить доступ к панели администратора как сотрудники, мы проверяем их существование с помощью отношения attendee. При обращении к event_instance.attendees
вы получите менеджера, а не всех участников. Чтобы получить всех участников, используйте event_instance.attendees.all().
Чтобы проверить, существует ли пользователь, мы используем .filter() и .exists():
class EventAdmin(admin.ModelAdmin):
def has_view_permission(self, request, obj=None):
user=request.user
if obj is None or user.is_superuser:
return True
return obj.attendees.filter(pk=user.pk).exists()
Чтобы отфильтровать представление списка для отображения только тех событий, которые пользователь может посетить, мы переопределим метод get_queryset
:
def get_queryset(self, request):
user=request.user
if user.is_superuser:
return qs
return qs.filter(attendees=user)