Как добавить пользовательское разрешение для модели User в django? - PullRequest
18 голосов
/ 11 октября 2011

в 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

Мой вопрос заключается в том, что мне следует делать, если я хочу добавить настраиваемое разрешение дляПользовательская модель?как 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?

Ответы [ 4 ]

8 голосов
/ 13 ноября 2012

Вы можете сделать что-то вроде этого:

в __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)
3 голосов
/ 10 марта 2012

Я не думаю, что здесь есть «правильный» ответ, но я использовал тот же код, что и вы, за исключением того, что я изменил Permission.objects.create на Permission.objects.get_or_create, и это сработало find для синхронизации с syncdb

2 голосов
/ 01 августа 2015

Обновленный ответ для 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)
0 голосов
/ 14 июня 2019

Это немного странно, но упоминать здесь все равно для справки.

У моего сайта есть общая модель под названием 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 позаботятся обо всем остальном.

...