Как добавить пользовательское разрешение для модели пользователя в django?
в django по умолчанию, когда syncdb запущен с установленным django.contrib.auth, он создает разрешения по умолчанию для каждой модели... например foo.can_change, foo.can_delete и foo.can_add. Чтобы добавить пользовательские разрешения для моделей, вы можете добавить класс Meta: под моделью и определить разрешения там, как описано здесь https://docs.djangoproject.com/en/dev/topics/auth/#custom-permissions
Мой вопрос: что мне делать, если я хочу добавить пользовательские разрешения для модели User? как foo.can_view. Я мог бы сделать это со следующим фрагментом,
ct = ContentType.objects.get(app_label='auth', model='user')
perm = Permission.objects.create(codename='can_view', name='Can View Users',
content_type=ct)
perm.save()
Но я хочу что-то, что хорошо играет с syncdb, например класс Meta под моими пользовательскими моделями. Должен ли я просто иметь их в классе Meta: в UserProfile, так как это способ расширить модель пользователя. но является ли это правильным способом? Разве это не связало бы его с моделью UserProfile?
Ответы
Ответ 1
Вы можете сделать что-то вроде этого:
в __init__.py
вашего приложения Django добавьте:
from django.db.models.signals import post_syncdb
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import Permission
# custom user related permissions
def add_user_permissions(sender, **kwargs):
ct = ContentType.objects.get(app_label='auth', model='user')
perm, created = Permission.objects.get_or_create(codename='can_view', name='Can View Users', content_type=ct)
post_syncdb.connect(add_user_permissions, sender=auth_models)
Ответ 2
Я не думаю, что здесь есть "правильный" ответ, но я использовал тот же самый код, что и вы, за исключением того, что я изменил Permission.objects.create
на Permission.objects.get_or_create
, и это сработало, чтобы синхронизировать с syncdb
Ответ 3
Обновленный ответ для Django 1.8. Сигнал pre_migrate
используется вместо pre_syncdb
, поскольку syncdb устарел, и документы рекомендуют использовать pre_migrate
вместо post_migrate
, если сигнал изменит базу данных. Кроме того, @receiver
используется для подключения add_user_permissions
к сигналу.
from django.db.models.signals import pre_migrate
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import Permission
from django.conf import settings
from django.dispatch import receiver
# custom user related permissions
@receiver(pre_migrate, sender=auth_models)
def add_user_permissions(sender, **kwargs):
content_type = ContentType.objects.get_for_model(settings.AUTH_USER_MODEL)
Permission.objects.get_or_create(codename='view_user', name='View user', content_type=content_type)
Ответ 4
Это немного глупо, но упоминать это здесь для справки.
У моего сайта есть общая модель Setting
, в которой хранятся различные настройки, относящиеся к сайту, которые я хочу, чтобы определенные пользователи могли редактировать, без необходимости проходить через моего разработчика (например, ограничение регистрации, или адрес, или стоимость элементов и т.д.).).
Все разрешения, которые плохо отображаются на других моделях (например, "Отправить электронное письмо с напоминанием пароля учащемуся", "Создать отчет о сверке платежей", "Создать квитанцию PDF"), которые действительно относятся только к страницам, которые просматриваются в области администратора. получить свалку на эту модель Setting
.
Например, вот модель:
class Setting(models.Model):
name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(editable=False)
description = models.TextField()
value = models.TextField()
class Meta:
#for permissions that don't really relate to a particular model, and I don't want to programmatically create them.
permissions = (
("password_reminder", "Send Password Reminder"),
("generate_payment_reconciliation_report", "Generate Payment Reconciliation Report"),
("generate_pdf_receipt", "Generate PDF Receipt"),
)
Каждая из этих настроек строго связана с моделью Setting
? Нет, именно поэтому я сказал, что это немного глупо. Но хорошо, что теперь я могу просто сбросить все эти разрешения здесь, а команды миграции Django позаботятся обо всем остальном.