Ограничение доступа в django на уровне модели - PullRequest
0 голосов
/ 18 января 2012

У меня есть модель, и я хотел бы ограничить доступ к объектам на основе уровня аутентификации пользователя.Анонимные пользователи могут видеть только подмножество объектов, в то время как авторизованные пользователи имеют доступ ко всем объектам.Читая книгу о django, я обнаружил, что могу использовать в своих представлениях проверки вроде is_authenticated () и реализовывать свою логику на основе этого условия.Но я не хочу, чтобы эти проверки разбрызгивались по всему моему коду, вместо этого я хотел бы иметь возможность придать своим моделям некоторый интеллект: модели должны делать доступными только объекты, видимые для разрешений текущего пользователя.

Вот несколько моделей, с которыми я работаю:

class Collection(models.Model):
    VISIBILITY_CHOICES = (
    ('P', 'Private'),
    ('SP', 'Semi-Private'),
    ('PUB', 'Public')
    )

    name = models.CharField(max_length=40)
    visibility = models.CharField(max_length=3, choices=VISIBILITY_CHOICES)
    category = models.CharField(max_length=50)


class Image(models.Model):
    image = models.ImageField(upload_to= get_upload_to)
    collection = models.ForeignKey(Collection)

Пример запроса, который я делаю: collection_ids = Image.objects.values_list ('collection',flat = True) .distinct () - в этом случае я бы хотел проверить только те идентификаторы коллекции, которые пользователь имеет право просматривать (т. е. общедоступный / частный / полуприватный).

возможно, или я должен поместить логику авторизации в мои представления?

Ответы [ 2 ]

1 голос
/ 18 января 2012

Установка аутентификации на модели - неправильное место для этой логики.Представления - это именно то место, где должна жить эта логика, поэтому django предоставляет различные аутентификаторы декорации для защиты представлений, таких как login_required ()

Задача моделей - обеспечить уровень доступа к базе данных на уровне данных.,Затем вы должны создать любое количество представлений, чтобы визуализировать данные так, как вы хотите.Если вам нужны анонимные представления данных, создайте представление, которое проверяет, прошел ли пользователь аутентификацию, и соответствующим образом форматирует данные.

0 голосов
/ 18 января 2012

Обратите внимание, что в приведенном вами примере запроса (Image.objects.values_list('collection',flat=True).distinct()) request никогда не упоминается - так как этот запрос сможет проверить текущего пользователя?

Но это не значит, что вы должны делать это в представлениях - вы можете добавить методы к самой модели или даже создать подкласс QuerySet, чтобы добавить метод для проверки текущего запроса, например .filter(foo=bar).allowed_for_user(user).

Смотрите этот ответ:

https://stackoverflow.com/a/4576649/16361

Какая ссылка на ваш древний пост в вашем блоге действительно правдива, хотя я, кажется, нарушил ссылку в этом ответе, извините - правильный URL-адрес:

http://adam.gomaa.us/blog/2009/feb/16/subclassing-django-querysets/

РЕДАКТИРОВАТЬ: более новая статья:

http://zmsmith.com/2010/04/using-custom-django-querysets/

Кроме того, просто чтобы прояснить - сам код не должен жить в ваших представлениях, но в конечном итоге необходимо будет так или иначе задействовать объект запроса, поэтому вам придется вызвать это с твоей точки зрения.

...