Создание пользовательских разрешений на доступ к формам / проверка в django admin - PullRequest
0 голосов
/ 17 апреля 2019

Я использую модель «Задача» для создания операций / административных задач на панели инструментов.У каждой задачи есть цессионарий и рецензент.Уполномоченный завершает задачу, проходя несколько проверок, и рецензент проверяет их работу, причем обе они требуют, чтобы каждый пользователь редактировал проверку, но ни один из пользователей не должен иметь доступа или изменять результаты другого.

Если цессионарий просматривает задание (с встроенными проверками), он должен иметь возможность изменять только элементы «результата» и «комментария» проверки, тогда как рецензент может редактировать только «review_result» иЭлементы "reviewer_comment".

Чтобы проверить это, мне нужно использовать тот факт, что с учетом check текущий пользователь, редактирующий страницу, равен check.task.assignee или check.task.reviewer.

Я не могу найти простой способ сделать это, даже используя django-guardian , так как для этого требуются разрешения на уровне поля, а не уровня объекта.Я рассмотрел вопрос об использовании валидации modelForm, но не могу найти способ доступа к пользователю из модели с помощью некоторых хаков, таких как django-cuser .

Есть ли другая архитектура, которая позволила бы это?Единственный способ продвинуться вперед, который я вижу, - это использовать django-guardian в сочетании с двумя проверками, check и checkReview, и устанавливать права доступа на уровне объекта, когда выбираются уполномоченный и рецензент.

class Task(PolymorphicModel):
    date_created = models.DateTimeField(auto_created=True)
    date_accepted = models.DateTimeField(null=True)
    date_reviewed = models.DateTimeField(null=True)
    date_closed = models.DateTimeField(null=True)
    state = FSMField(default="open")

    assignee = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        related_name="assigned_tasks",
        related_query_name="assigned_task",
    )
    reviewer = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        related_name="review_tasks",
        related_query_name="review_task",
    )

class Check(PolymorphicModel):
    result = models.BooleanField(null=True)
    comment = models.CharField(max_length=500, null=True, blank=True)
    review_result = models.BooleanField(null=True)
    reviewer_comment = models.CharField(max_length=500, null=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE)

1 Ответ

0 голосов
/ 17 апреля 2019

Правильный метод для достижения этой цели - переопределить метод get_readonly_fields для InlineModelAdmin (в вашем классе Inline).

def get_readonly_fields(self, request, obj=None):
    if obj is None:
        logger.error("An admin has created a check from the dashboard (this should not happen)!")
        return []
    user = request.user
    fields = [field.name for field in self.opts.local_fields]
    if user == obj.assignee:
        fields.remove(['result', 'comment'])
    elif user == obj.reviewer:
        fields.remove(['review_result', 'reviewer_comment'])
    return fields
...