Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

5.1 Разрешения на уровне пользователя
3 из 3 шагов пройдено

В приложении blog для модели Blog создадим вьюху для добавления поста. Добавлять пост может только пользователь у которого будет разрешение add_post.

Если бы мы использовали вьюху создания поста в функциональном стиле, то для разграничения доступа, мы могли использовать декоратор permission_required:

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('blog.add_post', raise_exception=True)
def add_post(request):
    #Код для добавления нового поста
    return render(request)


Также мы можем проверить есть ли у данного пользователя определенное разрешение или нет, с помощью метода has_perm:

def add_post(request):
    #Проверяем есть ли у данного пользователя разрешение для добавления поста 
    #Если такого разрешения нет, то выкидываем исключение PermissionDenied
    if not request.user.has_perm('blog.add_post'):
        raise PermissionDenied
    # Бизнес-логика для добавления поста

Для неаутентифицированного пользователя AnonymousUser метод has_perm всегда будет возвращать False.


Мы будем работать на уровне классов, добавим в файл blog/views.py следующий код:

from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import CreateView

from blog.models import Post


class CreatePostView(PermissionRequiredMixin, CreateView):
    permission_required = 'blog.add_post'
    model = Post
    fields = ('name', 'content')
    template_name = "post.html"


Здесь мы используем миксин PermissionRequiredMixin, потому что мы используем CreateView для создания нового объекта модели поста.

У миксина  PermissionRequiredMixin в поле permission_required мы задаём разрешение: blog.add_post.

Если пользователь аутентифицирован , но при этом у него нет разрешения добавлять посты, то ему будет отказано в доступе к этой вьюхе и будет возвращен код 403(Доступ воспрещен).

А если у него будет разрешение blog.add_post, то он сможет создать новый пост.


Добавим наши маршруты в главный urls.py проекта:

from django.contrib import admin
from django.urls import path, include

from blog import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('created/', views.CreatePostView.as_view(), name='post_created'),
    path("accounts/", include("django.contrib.auth.urls")),
]


Создадим шаблон post.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django</title>
</head>
<body>
    Добавление поста разрешено пользователю {{ request.user.username }}
</body>
</html>


Добавим шаблон входа на сайт registration/login.html:

    <h2> Login </h2>
    <form method="post">
        {{ form.as_p }}
        {% csrf_token %}
        <p><input type="submit" value="Login"></p>
    </form>


Войдем в админ панель и создадим еще одного пользователя с именем Николай, но не будем ему выдавать права.

В итоге мы имеем 2х пользователей. Пользователь Василий имеет разрешение blog.add_post, а пользователь Николай не имеет данного разрешения:



Осталось проверить работу, перейдем по адресу http://127.0.0.1:8000/accounts/login/ и авторизуемся под пользователем Василий.

Далее перейдем по адресу -  http://127.0.0.1:8000/created/ и мы видим, что пользователю разрешены действия по добавлению постов:


Теперь еще раз перейдем по адресу http://127.0.0.1:8000/accounts/login/ и авторизуемся под пользователем Николай.

Далее перейдем по адресу  http://127.0.0.1:8000/created/ и мы получаем ошибку 403, то есть доступ запрещен:


В данном шаге мы рассмотрели на практике Django permissions, которые позволяют разграничивать доступ к объектам. Это очень мощная штука , которая позволяет нам легко ограничивать доступ к добавлению, редактированию, удалению объектов разных моделей.


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

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

 

Мы будем работать на уровне классов:

from django.contrib.auth.mixins import PermissionRequiredMixin


class CreatePostView(PermissionRequiredMixin, CreateView):
    permission_required = 'blog.add_post'
    model = Post
    fields = ('name', 'content')
    template_name = "post.html"


Здесь мы используем миксин PermissionRequiredMixin, потому что мы используем CreateView для создания нового объекта модели поста.

@No_Name, Поправил. Спасибо.