В приложении 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, которые позволяют разграничивать доступ к объектам. Это очень мощная штука , которая позволяет нам легко ограничивать доступ к добавлению, редактированию, удалению объектов разных моделей.