/ заметка

Система прав в Django

Когда мы говорим о какихлибо (любых) правах, мы подразумеваем три параметра: субъект, объект, действие.

Когда мы говорим о каких-либо (любых) правах, мы подразумеваем три параметра: субъект, объект, действие.

Как это выражается в коде на примере кастомных прав? Мы создаем новое право, прикрепляя его к сущности, прописывая на уровне модели. Это просто ярлычок, название права, прикрепленное к конкретной сущности. Это прикрепление ничего не ограничивает и не добавляет. Просто есть соглашение, что если право относится к какой-то сущности, его нужно прописать в её модели. Это удобно, плюс навигация по правам в админке Django построена на этой основе. На этом этапе мы всё еще не прикрепили право к объекту.

class Book(models.Model):
    ...

	class Meta:
		permissions = [
			('can_view_sales_count', 'Может видеть количество продаж'),
		]
	

Действие и объект прописывается в бизнес-логике. Это может быть что-то типа:

def get_fields(self, request, obj=None):
    if not hasattr(self, 'fields'):
        return super().get_fields(request, obj)
    
    all_fields = list(self.fields)
    if request.user.has_perm('books.can_view_sales_count'):
        all_fields.append('sales_count')
    return all_fields

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

Помимо кастомных прав, в Django есть встроенные права, относящиеся к админке Django:

  • has_add_permission
  • has_change_permission
  • has_view_permission
  • has_delete_permission

Эти права менее универсальны, но более удобны для использования именно в админке Django. Обычный пользователь по умолчанию не имеет никаких прав в админке. Буквально, если разрешить ему логиниться в админскую часть, но не выдавать никаких прав, он увидит пустую страницу. Таким образом, выдавая какие-то права, мы идем из ситуации, когда никаких прав нет в сторону суперпользователя, который обладает всеми правами по умолчанию.

Проблемы начинаются, когда нам надо совместить кастомные права со встроенными.