Право собственности на объекты в Джанго - PullRequest
10 голосов
/ 16 июня 2009

Мне интересно, как можно создать простую систему «владения объектами» с моделями django, чтобы по умолчанию ее мог редактировать только владелец объекта.

Я пытаюсь разрешить группе «Управление» редактировать все объекты от имени владельцев объектов, и на данный момент добавлено специальное разрешение:

class Meta:
    permissions     = (
        ("manage_object", "Can manage objects"),
    )

Чтобы установить «владение», я поиграл с идеей добавить def к модели:

def owner(self):
    return self.user

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

if request.user is object.owner:
    # ... do stuff
elseif request.user.has_perm.can_manage:  # this line is probably not right
    # ... do something else

... и затем представить различные элементы пользовательского интерфейса на уровне шаблона.

Итак, вопрос:

  • Какие недостатки / преимущества есть в этом подходе?
  • есть рекомендации?
  • или любые другие ранее реализованные методы?

Лучшее спасибо!

Ответы [ 3 ]

17 голосов
/ 16 июня 2009

Мой подход заключается в добавлении метода к модели:

class YourModelWithOwnership(models.model):
    ...

    def user_can_manage_me(self, user):
        return user == self.user or user.has_perm('your_app.manage_object')

Затем я вызываю этот метод всякий раз, когда требуется проверка разрешения, и предпринимаю некоторые действия в зависимости от результата. Так что для представления это будет

from django.shortcuts import get_object_or_404
...

def view_func(request, item_id):
    item = get_object_or_404(YourModelWithOwnership, id=item_id) # or whatever is needed to get the object
    if not item.user_can_manage_me(request.user):
        # user not allowed to manage
        ...
    else:
        ...

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

class CannotManage(Exception):
    pass

... и добавьте еще один метод к модели:

from django.db import models
from django.shortcuts import get_object_or_404

class YourModelWithOwnership(models.model):
    ...

    @classmethod
    def get_manageable_object_or_404(cls, user, *args, **kwds):
        item = get_object_or_404(cls, *args, **kwds)
        if not item.user_can_manage_me(user):
            raise CannotManage
        return item

Тогда в функциях просмотра это можно использовать:

def view_func(request, item_id):
    item = YourModelWithOwnership.get_manageable_object_or_404(request.user, id=item_id)
    ...

Это, конечно, вызовет исключение, когда пользователь не является владельцем и не имеет соответствующего разрешения. Это исключение может быть обработано в методе process_exception() пользовательского класса промежуточного программного обеспечения *1018*, так что существует единый обработчик для всех случаев, когда пользователю не разрешено связываться с объектом.

2 голосов
/ 20 июня 2009

Некоторое время назад я написал обычную технику для этого в админе . Вы можете прочитать это, чтобы увидеть, как работает реализация.

0 голосов
/ 16 июня 2009

Вы можете посмотреть в RowLevelPermissions ветку. Хотя он не был включен даже в бета-версию 1.1, я думаю, что он все еще нуждается в доработке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...