Как определить разрешения на основе поля модели в Django 2.2 / Python 3.5 - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть пользовательская модель пользователя с полем, определяющим уровень пользователя. Я хотел бы использовать это поле для ограничения определенных представлений / конечных точек API и других функций.

То есть для представлений на основе классов или маршрутов URL, как я могу использовать это свойство, т. Е. Если пользователь вошел в систему и is_end_user, то не разрешает доступ к CBV 1 и аналогичным логам c?

Роли здесь, то есть администратор, не совпадают с ролями суперпользователя, поэтому ни одна из них не имеет доступа к административному бэкэнду Django, но я хочу сделать отдельные "административные" представления / панели для разных групп пользователей - также API должен быть доступен только пользователям с id_end_user == True.

Я использую Django 2.2 и Python 3.5

Определение модели:

class AppUser(AbstractBaseUser, PermissionsMixin):
    [...]
    USER_TYPE_CHOICES = (
            (1, 'appuser'),
            (2, 'moderator'),
            (3, 'intern'),
            (4, 'admin'),
    )
    [...]

    def _get_user_type(self):
            return self.user_type

     @property
        def is_end_user(self):
            if (self._get_user_type() is 1):
                return True
            else:
                return False
    [...]

Ответы [ 2 ]

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

UserPassesTestMixin должен делать именно то, что вам нужно, но было бы немного полезнее накатить свои собственные миксины. Вот пример чего-то похожего на то, что вам нужно.

class UserMixin(object):
    allowed_roles = None

    def dispatch(self, request, *args, **kwargs):
        if self.allowed_roles:
            if request.role not in self.allowed_roles:
                messages.add_message(request, messages.ERROR, "You don't have permission to view the page requested.")
                return HttpResponseRedirect(reverse('index'))
        return super(UserMixin, self).dispatch(request, *args, **kwargs)

Используйте это так:

class MyViewThatOnlyAdminsShouldSee(LoginRequiredMixin, UserMixin):
    allowed_roles = [AppUser.ADMIN]

В моем случае я просто перенаправил на домашнюю страницу сайта с сообщение. Вы также можете бросить 403 или 404 в зависимости от ваших потребностей

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

Хорошее место, чтобы узнать, как что-то сделать, это посмотреть, как Django реализует это самостоятельно. Вот модуль декораторов для прав пользователя в Django.

Вот код для login_required:

def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
    """
    Decorator for views that checks that the user is logged in, redirecting
    to the log-in page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_authenticated,
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

Так что вы должны иметь возможность использовать что-то вроде для is_end_user:

from django.contrib.auth import REDIRECT_FIELD_NAME

def end_user_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, redirect_url=None):
    """
    Decorator for views that checks that the user is an end_user.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_end_user,
        login_url=redirect_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

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

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