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

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

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

Django предоставляет из коробки систему аутентификации и авторизации(permission) пользователей. Эта система позволяет проверять учетные данные пользователей и определять права доступа для пользователей.

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

Приступим к изучению разрешений на практике, для начала создадим новый проект с любым названием. После создания нового проекта на Django, то в файле settings.py вы можете увидеть, что система аутентификации django.contrib.auth уже включена.

Также по умолчанию включена система типов контента Django django.contrib.contenttypes, которая позволяет связывать разрешения(permissons) с создаваемыми вами моделями.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]


С этими настройками после выполнения команды:

python manage.py migrate

 в базе данных создаются необходимые таблицы для моделей связанных с аутентификацией и с разрешениями(permissions).


Таким образом, Django имеет встроенную систему разрешений(permissions). Эта система позволяет назначать разрешения конкретным пользователям и группам пользователей.


Создадим в нашем проекте новое приложение:

python manage.py startapp blog


В файле models.py создадим модель Post:

from django.db import models


class Post(models.Model):
    name = models.CharField(max_length=255)
    content = models.TextField()

    def __str__(self):
        return self.name


Добавим в настройки Django наше приложении и после выполним миграции, чтобы в базе данных создалась таблица blog_post. Также в таблицу auth_permission добавляются четыре разрешения(permissions) ассоциированных с моделью Post:


Django для нашей модели Post после выполнения миграций создала четыре разрешения:

  • Разрешение add (в нашем случае add_post) позволяет пользователям добавлять экземпляры модели.
  • Разрешение change (в нашем случае change_post) позволяет пользователям редактировать экземпляры модели.
  • Разрешение delete (в нашем случае delete_post) позволяет пользователям удалять экземпляры модели.
  • Разрешение view (в нашем случае view_post) позволяет пользователям просматривать экземпляры данной модели.


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

  • blog.add_post, где blog - это имя приложения(app), add - это действие(action), а post - это название модели(modelname).
  • blog.change_post, где blog - это имя приложения(app), change - это действие(action), а post - это название модели(modelname).
  • blog.delete_post, где blog - это имя приложения(app), delete - это действие(action), а post - это название модели(modelname).
  • blog.view_post, где blog - это имя приложения(app), view - это действие(action), а post - это название модели(modelname).


В админке Django, если мы зайдем под правами суперпользователя , то мы можем назначать эти права определенным пользователям. Но сначала откроем Shell и попробуем поработать в нём. Выполним:

python manage.py shell


Первым делом импортируем нужные модули:

from django.contrib.auth import get_user_model
from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType

from blog.models import Post

У каждой модели есть атрибут <name_model>_permissions. Выполним следующие команды, которые нам покажут все разрешения для модели Post.

content_type = ContentType.objects.get_for_model(Post)
post_permission = Permission.objects.filter(content_type=content_type)
print([perm.codename for perm in post_permission])

 
И получим результат, аналогичный как и в нашей базе данных.

['add_post', 'change_post', 'delete_post', 'view_post']


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

user = User.objects.create_user(username="Василий", password="test", email="test@user.com")

 
Теперь давайте проверять права доступа у данного пользователя:

>>> print(user.has_perm("blog.view_post"))
False


Попробуем установить права этому пользователю:

>>> for perm in post_permission:
...     user.user_permissions.add(perm)
... 
>>> print(user.has_perm("blog.view_post"))
False

Почему мы получили False? Это происходит потому, что разрешения Django не принимаются до тех пор, пока вы не создадим новый экземпляр пользователя.


Проверим разрешения еще раз, заново извлекая пользователя.

>>> user = get_user_model().objects.get(email="test@user.com")
>>> print(user.has_perm("blog.view_post"))
True


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

from django.contrib.auth.models import User

superuser = User.objects.create_superuser(
    username="admin", password="123456", email="admin@test.com"
)


Проверим разрешения на просмотр постов: 

>>> print(superuser.has_perm("blog.view_post"))
True


Мы можем также проверить разрешения на не существующие права доступа:

>>> print(superuser.has_perm("test.add_bar"))
True


Суперпользователь - это тип пользователя в Django, который имеет все разрешения в системе. Будь то пользовательские разрешения или разрешения, созданные Django, суперпользователи имеют доступ ко всему.

Давайте войдем в админ панель и посмотрим разрешения у нашего пользователя, мы видим что в User permissions у него добавлены все разрешения связанные с моделью Post:


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

После создания нового проекта на Django, то в файле settings.py вы можете увидеть, что система аутентификации django.contrib.auth уже включена.

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

@Георгий_Тимофеев, нужно, добавил этот момент в лекцию. Спасибо за замечание.