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

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

5.2 Разрешения на уровне группы
1 из 1 шага пройден

Необходимость каждый раз назначать разрешения пользователям утомительна и не масштабируема. Могут быть случаи, когда вам захочется добавить новые разрешения для набора пользователей. Здесь в игру вступают группы Django.

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

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


Для создания группы вам понадобится Group модель из django.contrib.auth.models.

Создадим группы для следующих ролей:

  • Author: Может просматривать и добавлять сообщения.
  • Editor: Может просматривать, добавлять и редактировать сообщения.
  • Publisher: Может просматривать, добавлять, редактировать и удалять сообщения.


Запустим шелл, выполнив команду:

python manage.py shell


И импортируем необходимые модули:

from django.contrib.auth.models import Group, User, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

from blog.models import Post


Далее создадим новые группы для пользователей:

author_group, created = Group.objects.get_or_create(name="Author")
editor_group, created = Group.objects.get_or_create(name="Editor")
publisher_group, created = Group.objects.get_or_create(name="Publisher")

Затем разрешение может быть назначено модели через атрибут post_permissions.

post_content_type = ContentType.objects.get_for_model(Post)
post_permission = Permission.objects.filter(content_type=post_content_type)

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


Выполним следующий запрос, чтобы назначить нашим группам необходимые права:

for perm in post_permission:
    if perm.codename == "delete_post":
        publisher_group.permissions.add(perm)
    elif perm.codename == "change_post":
        editor_group.permissions.add(perm)
        publisher_group.permissions.add(perm)
    else:
        author_group.permissions.add(perm)
        editor_group.permissions.add(perm)
        publisher_group.permissions.add(perm)


Далее создадим нового пользователя и добавим его в группу авторов:

user = User.objects.create_user(username="Максим", password="test", email="test@user.com")


Теперь давайте запустим сервер, войдем под пользователем Максим по ссылке - http://127.0.0.1:8000/accounts/login/

И перейдем на страницу http://127.0.0.1:8000/created/ и мы увидим что доступ запрещен:


Остановим работу сервера и снова запустим шелл, и импортируем снова необходимые модули:

from django.contrib.auth.models import Group, User, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

from blog.models import Post


Выберем нашу группу Author:

author_group = Group.objects.get(name="Author")


Далее выберем пользователя с именем Максим и добавим ему эту группу:

user = User.objects.get(username="Максим")
user.groups.add(author_group)


Осталось только проверить его права, Как мы помним, группа Author может просматривать и добавлять сообщения:

user = get_object_or_404(User, pk=user.id)
print(user.has_perm("blog.delete_post"))
print(user.has_perm("blog.change_post"))
print(user.has_perm("blog.view_post"))
print(user.has_perm("blog.add_post"))


И мы получим следующий результат:


Теперь давайте запустим сервер, и войдем на страницу http://127.0.0.1:8000/created/ под пользователем Максим:

Мы видим что у него появился доступ к добавлению постов. Теперь войдем в админ панель - http://127.0.0.1:8000/admin/.


Выберем нашего пользователя Максим и посмотрим его группу:

Мы видим что управлять группами для пользователей мы также можем и из админ-панели.


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


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

А откуда появилось post_permission?

@Илья_Перминов, ошибка все такая же у нас нет post_permission
 

In [2]: author_group, created = Group.objects.get_or_create(name="Author")
   ...: editor_group, created = Group.objects.get_or_create(name="Editor")
   ...: publisher_group, created = Group.objects.get_or_create(name="Publisher")

   ...:     if perm.codename == "delete_post":
   ...:         publisher_group.permissions.add(perm)
   ...:     elif perm.codename == "change_post":
   ...:         editor_group.permissions.add(perm)
   ...:         publisher_group.permissions.add(perm)
   ...:     else:
   ...:         author_group.permissions.add(perm)
   ...:         editor_group.permissions.add(perm)
   ...:         publisher_group.permissions.add(perm)
   ...: 
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [3], line 1
----> 1 for perm in post_permission:
      2     if perm.codename == "delete_post":
      3         publisher_group.permissions.add(perm)

NameError: name 'post_permission' is not defined

   ...:     if perm.codename == "delete_post":
   ...:         publisher_group.permissions.add(perm)
   ...:     elif perm.codename == "change_post":
   ...:         editor_group.permissions.add(perm)
   ...:         publisher_group.permissions.add(perm)
   ...:     else:
   ...:         author_group.permissions.add(perm)
   ...:         editor_group.permissions.add(perm)
   ...:         publisher_group.permissions.add(perm)
   ...: 
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [4], line 1
----> 1 for perm in post_permission:
      2     if perm.codename == "delete_post":
      3         publisher_group.permissions.add(perm)

NameError: name 'post_permission' is not defined

In [5]: print(perm.codename for perm in post_permission)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [5], line 1
----> 1 print(perm.codename for perm in post_permission)

NameError: name 'post_permission' is not defined

In [6]: 
 

Изменен No Name

@No_Name, у кого такая же ошибка вставьте этот код он решит ее! Автор поправьте лекцию!

post_content_type = ContentType.objects.get_for_model(Post)
post_permission = Permission.objects.filter(content_type=post_content_type)

@Ilia_Boiarintsev@No_Name, Исправил, действительно наша ошибка.