django -rules: проблемы с настройкой в ​​шаблонах - PullRequest
0 голосов
/ 02 апреля 2020

Отказ от ответственности: я новичок в правилах django и django.

Я определил свою модель. Модель имеет 2 внешних ключа к пользовательской таблице. Создатель и руководитель. Экземпляры должны изменяться / обновляться персоналом, создателем или руководителем.

Я определил предикаты для is_creator и is_supervisor и создал правило:

@rules.predicate
def is_creator(user, mymodel):
    return mymodel.creator == user

@rules.predicate
def is_supervisor(user, mymodel):
    return mymodel.supervisor == user

can_edit = is_supervisor | is_creator | rules.is_staff

А в метаклассе моделей я добавил:

rules_permissions = {           
    'change': can_edit
}

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

{% block content %}
{% has_perm 'mymodel.change_mymodel' user instance as can_edit %}
{% if can_edit %}
<button type="button" class="btn btn-warning"><h6>Edit</h6></button>
{% endif %}
{% endblock %}

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

У меня есть вторая похожая функциональность для страницы индекса. Отображение только действий, для которых пользователи имеют привилегии. Опять же, суперпользователь видит все это, а тестовый пользователь - нет.

В этом случае ниже приведен предикат, который используется как разрешение «добавить» в другой модели:

@rules.predicate
def can_add_xyz(user):
    return rules.is_staff | rules.is_group_member("Add_XYZ")

Кажется, в обоих случаях все проверки, кроме is_staff, кажутся неудачными. Что я делаю не так?

1 Ответ

0 голосов
/ 03 апреля 2020

Есть две проблемы. Сначала запустите RTFM и сделайте это правильно:

В моем шаблоне я использовал has_perm entity_name.add_entity_name вместо использования, как описано в документации has_perm myapp.add_entity_name.

После исправления того, что предикаты теперь действительно вызывались и Я мог бы отладить их. И там появилась большая проблема. Я смог это исправить, но мне не понравилось это исправление.

Предикат:

@rules.predicate
def is_creator(user, mymodel):
    return mymodel.creator == user

Проблема в том, что в шаблоне, который я проверяю это разрешение, mymodel является связанной объект, генерируемый вложенным сериализатором django -rest-framework. Это означает, что экземпляр, используемый в шаблоне, который затем передается этому предикату, является не экземпляром mymodel, а OrderedDict, и, следовательно, я получаю исключение, подобное OrderedDict has no attribute 'creator'.

Еще одна проблема заключается в том, что создатель не является напрямую Django auth_user, но расширенный пользователь OneToOne. Так что mymodel.creator == user никогда не будет правдой.

@rules.predicate
def is_creator(user, mymodel):
    #if called from template as related entity,
    #mymodel is an OrderedDict from a serializer
    if isinstance(mymodel, collections.OrderedDict):        
        return mymodel["creator"] == user.userprofile.pk
    return mymodel.creator == user.userprofile

Это решает проблему, и теперь отображаются правильные вещи, но я не совсем доволен этим (проверка типа). Поэтому любые советы по улучшению этого положения по-прежнему приветствуются.

...