9đź‘Ť
You could do something like this:
in the __init__.py
of your Django app add:
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)
5đź‘Ť
I don’t think there is a “right” answer here, but i used the exact same code as you except i changed Permission.objects.create
to Permission.objects.get_or_create
and that worked find to sync with syncdb
- [Django]-How to solve CORS problem of my Django API?
- [Django]-Django – in memory sqlite in production
- [Django]-Django filter the model on ManyToMany count?
2đź‘Ť
An updated answer for Django 1.8. The signal pre_migrate
is used instead of pre_syncdb
, since syncdb is deprecated and the docs recommend using pre_migrate
instead of post_migrate
if the signal will alter the database. Also, @receiver
is used to connect add_user_permissions
to the signal.
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)
- [Django]-In Django, how do I select 100 random records from the database?
- [Django]-Why does pip fail with bad md5 hash for package?
- [Django]-Equivalent of get_or_create for adding users
1đź‘Ť
This is a bit hacky but mentioning it here anyway for reference.
My site has a generic model called Setting
, which stores various settings concerning the site I want certain users to be able to edit, without needing to go through me the developer (like registration limit, or an address, or the cost of items, etc).
All the permissions that don’t nicely map onto other models (eg “Send Password Reminder Email to Student”, “Generate Payment Reconciliation Report”, “Generate PDF Receipt”), which really just relate to pages that get viewed in the admin area, get dumped onto this Setting
model.
For example, here’s the model:
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"),
)
Do each of those settings strictly relate to the Setting
model? No, which is why I said this is a bit hacky. But it is nice that I can now just dump all those permissions here, and Django’s migration commands will take care of the rest.
- [Django]-How to get a GET request values' list in Django?
- [Django]-Django models, custom functions
- [Django]-Django request.is_ajax returning false
0đź‘Ť
As @leech pointed out in a comment on their answer, you can’t pass the name
parameter to get_or_create
directly. You have to include name as part of the defaults
dict. Otherwise you’ll get duplicate key errors.
Change the get_or_create
call from @Dzejkob’s answer to make it look like this:
perm, created = Permission.objects.get_or_create(
content_type=ct,
codename='can_view',
defaults={'name': 'Can View Users'},
)
- [Django]-Filter Queryset on empty ImageField
- [Django]-What is "add_fieldsets" for in UserAdmin in Django?
- [Django]-Name '_' is not defined