Я пытаюсь сделать так, чтобы только те люди, которые будут присутствовать на мероприятии, могли просматривать только те мероприятия, на которых они присутствуют. Как мне это сделать?

Я использую 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) 
Вернуться на верх