17๐
A new feature introduced in Django 1.7 is the ability to define the default permissions. As stated in the documentation if you set this to empty none of the default permissions will be created.
A working example would be:
class Blar1(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, unique = True, blank = False, null = False, verbose_name= "Name")
class Meta:
default_permissions = ()
21๐
UPDATE: Django 1.7 supports the customization of default permissions
Original Answer
The following is valid for Django prior to version 1.7
This is standard functionality of the auth contrib application.
It handles the post_syncdb signal and creates the permissions (the standard 3: add, change, delete, plus any custom ones) for each model; they are stored in the auth_permission table in the database.
So, they will be created each time you run the syncdb management command
You have some choices. None is really elegant, but you can consider:
-
Dropping the auth contrib app and provide your own authentication backend.
Consequences -> you will lose the admin and other custom apps built on top of the auth User model, but if your application is highly customized that could be an option for you
-
Overriding the behaviour of the post_syncdb signal inside the auth app (inside \django\contrib\auth\management__init__.py file)
Consequences -> be aware that without the basic permissions the Django admin interface wonโt be able to work (and maybe other things as well).
-
Deleting the basic permissions (add, change, delete) for each model inside the auth_permission table (manually, with a script, or whatever).
Consequences -> you will lose the admin again, and you will need to delete them each time you run syncdb.
-
Building your own Permission application/system (with your own decorators, middlewares, etc..) or extending the existing one.
Consequences -> none, if you build it well โ this is one of the cleanest solutions in my opinion.
A final consideration: changing the contrib applications or Django framework itself is never considered a good thing: you could break something and you will have hard times if you will need to upgrade to a newer version of Django.
So, if you want to be as clean as possibile, consider rolling your own permission system, or extending the standard one (django-guardian is a good example of an extension to django permissions). It wonโt take much effort, and you can build it the way it feels right for you, overcoming the limitations of the standard django permission system. And if you do a good work, you could also consider to open source it to enable other people using/improving your solution =)
- [Django]-In Django what is i18n?
- [Django]-Django model default sort order using related table field
- [Django]-How do I include a stacktrace in my Django 500.html page?
19๐
I struggled with this same problem for a while and I think Iโve come up with a clean solution. Hereโs how you hide the permissions for Djangoโs auth app:
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.contrib.auth.models import Permission
class MyGroupAdminForm(forms.ModelForm):
class Meta:
model = MyGroup
permissions = forms.ModelMultipleChoiceField(
Permission.objects.exclude(content_type__app_label='auth'),
widget=admin.widgets.FilteredSelectMultiple(_('permissions'), False))
class MyGroupAdmin(admin.ModelAdmin):
form = MyGroupAdminForm
search_fields = ('name',)
ordering = ('name',)
admin.site.unregister(Group)
admin.site.register(MyGroup, MyGroupAdmin)
Of course it can easily be modified to hide whatever permissions you want. Let me know if this works for you.
- [Django]-In-Memory broker for celery unit tests
- [Django]-How to implement breadcrumbs in a Django template?
- [Django]-How do you detect a new instance of the model in Django's model.save()
7๐
ShadowCloud gave a good rundown. Hereโs a simple way to accomplish your goal.
Add these line in your admin.py:
from django.contrib.auth.models import Permission
admin.site.register(Permission)
You can now add/change/delete permissions in the admin. Remove the unused ones and when you have what you want, go back and remove these two lines from admin.py.
As was mentioned by others, a subsequent syncdb will put everything back.
- [Django]-Effects of changing Django's SECRET_KEY
- [Django]-How to define two fields "unique" as couple
- [Django]-Django form with BooleanField always invalid unless checked
4๐
Built on top of the solution by @pmdarrow, Iโve come up with a relatively clean solution to patch the Django admin views.
See: https://gist.github.com/vdboor/6280390
It extends the User
and Group
admin to hide certain permissions.
- [Django]-Django admin โ inline inlines (or, three model editing at once)
- [Django]-Where can I find the error logs of nginx, using FastCGI and Django?
- [Django]-Get class name for empty queryset in django
2๐
You canโt easily delete those permissions (so that syncdb wonโt put them back), but you can hide them from the admin interface. The idea is, as described by others, to override the admin forms but you have to do this for both users and groups.
Here is the admin.py with the solution:
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import GroupAdmin, UserAdmin
from django.contrib.auth.forms import UserChangeForm
#
# In the models listed below standard permissions "add_model", "change_model"
# and "delete_model" will be created by syncdb, but hidden from admin interface.
# This is convenient in case you use your own set of permissions so the list
# in the admin interface wont be confusing.
# Feel free to add your models here. The first element is the app name (this is
# the directory your app is in) and the second element is the name of your model
# from models.py module of your app (Note: both names must be lowercased).
#
MODELS_TO_HIDE_STD_PERMISSIONS = (
("myapp", "mymodel"),
)
def _get_corrected_permissions():
perms = Permission.objects.all()
for app_name, model_name in MODELS_TO_HIDE_STD_PERMISSIONS:
perms = perms.exclude(content_type__app_label=app_name, codename='add_%s' % model_name)
perms = perms.exclude(content_type__app_label=app_name, codename='change_%s' % model_name)
perms = perms.exclude(content_type__app_label=app_name, codename='delete_%s' % model_name)
return perms
class MyGroupAdminForm(forms.ModelForm):
class Meta:
model = Group
permissions = forms.ModelMultipleChoiceField(
_get_corrected_permissions(),
widget=admin.widgets.FilteredSelectMultiple(('permissions'), False),
help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.'
)
class MyGroupAdmin(GroupAdmin):
form = MyGroupAdminForm
class MyUserChangeForm(UserChangeForm):
user_permissions = forms.ModelMultipleChoiceField(
_get_corrected_permissions(),
widget=admin.widgets.FilteredSelectMultiple(('user_permissions'), False),
help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.'
)
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
admin.site.unregister(Group)
admin.site.register(Group, MyGroupAdmin)
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
- [Django]-Django: Error: Unknown command: 'makemigrations'
- [Django]-Django Admin ManyToManyField
- [Django]-How to run celery as a daemon in production?
0๐
If you are creating your own user management backend and only want to show your custom permissions you can filter out the default permissions by excluding permission with a name that starts with โCanโ.
WARNING:
You must remember not to name your permissions starting with โCanโ!!!!
If they decide to change the naming convention this might not work.
With credit to pmdarrow this is how I did this in my project:
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import Permission
from django.contrib import admin
class UserEditForm(UserChangeForm):
class Meta:
model = User
exclude = (
'last_login',
'is_superuser',
'is_staff',
'date_joined',
)
user_permissions = forms.ModelMultipleChoiceField(
Permission.objects.exclude(name__startswith='Can'),
widget=admin.widgets.FilteredSelectMultiple(_('permissions'), False))
- [Django]-Are there any plans to officially support Django with IIS?
- [Django]-What are the best practices to use AngularJS with Django
- [Django]-Django โ pisa : adding images to PDF output
0๐
If you want to prevent Django from creating permissions, you can block the signals from being sent.
If you put this into a management/init.py in any app, it will bind to the signal handler before the auth framework has a chance (taking advantage of the dispatch_uid debouncing).
from django.db.models import signals
def do_nothing(*args, **kwargs):
pass
signals.post_syncdb.connect(do_nothing, dispatch_uid="django.contrib.auth.management.create_permissions")
signals.post_syncdb.connect(do_nothing, dispatch_uid="django.contrib.auth.management.create_superuser")
- [Django]-Querying full name in Django
- [Django]-Why does my Django admin site not have styles / CSS loading?
- [Django]-Celery unable to use redis
0๐
Iโm coming here somewhat frustrated, since what I believe to be the "correct" answer is mentioned here:
UPDATE: Django 1.7 supports the customization of default permissions
But I cannot find any examples of carrying this out. In my case I wanted to remove "add" permission from a few models (but not all), because for those models the add permission is implied by other things. This is how it looks in the model definition:
class MyModel(models.Model):
class Meta:
default_permissions = ('change', 'delete', 'view')
You need to cover 2 things in the migration. The first thing is the change to the Meta
, which will be covered by a simple makemigrations
command. This gets added to the operations
and looks loosely like this:
migrations.AlterModelOptions(
name='mymodel',
options={
'default_permissions': ('change', 'delete', 'view'),
},
),
Now you need a data migration to delete the entry from the permissions table, assuming that this is an existing model. New models will not need either of these migration steps, so thatโs nice. So add this to operations
migrations.RunPython(delete_add_permission),
with the corresponding method defined separately.
def delete_add_permission(apps, schema_editor):
Permission = apps.get_model('auth', 'Permission')
perm = Permission.objects.filter(name='add_mymodel').first()
if perm:
perm.delete()
- [Django]-How can django sql queries use case insensitive and contains at the same time?
- [Django]-Cannot apply DjangoModelPermissions on a view that does not have `.queryset` property or overrides the `.get_queryset()` method
- [Django]-Django bytesIO to base64 String & return as JSON