87

I understand the basic user stuff. I know authentication, login, creating accounts, etc. But now I want to work on groups and permissions.

Where is the documentation for django groups/permissions? This is not it: http://docs.djangoproject.com/en/dev/topics/auth/

user
  • 17,781
  • 20
  • 98
  • 124
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

1 Answers1

123

I suppose the first question you need to ask are what permissions do you need and what sort. By what sort, I mean do you want Model- or Object-level. To clarify the difference say you have a model Car. If you want to give permissions on all cars, then Model-level is appropriate, but if you want to give permissions on a per-car basis you want Object-level. You may need both, and this isn't a problem as we'll see.

For Model permissions, Django handles these for you... mostly. For each model Django will create permissions in the form 'appname.permissionname_modelname'. If you have an app called 'drivers' with the Car model then one permission would be 'drivers.delete_car'. The permissions that Django automatically creates will be create, change, and delete. For some strange reason they decided not to include read permissions from CRUD, you will have to do this yourself. Note that Django decided to change CRUD's 'update' to 'change' for some reason. To add more permissions to a model, say read permissions, you use the Meta class:

class Car( models.Model ):
    # model stuff here
    class Meta:
        permissions = ( 
            ( "read_car", "Can read Car" ),
        )

Note that permissions is a set of tuples, where the tuple items are the permission as described above and a description of that permission. You don't have to follow the permname_modelname convention but I usually stick with it.

Finally, to check permissions, you can use has_perm:

obj.has_perm( 'drivers.read_car' )

Where obj is either a User or Group instance. I think it is simpler to write a function for this:

def has_model_permissions( entity, model, perms, app ):
    for p in perms:
        if not entity.has_perm( "%s.%s_%s" % ( app, p, model.__name__ ) ):
            return False
    return True

Where entity is the object to check permissions on (Group or User), model is the instance of a model, perms is a list of permissions as strings to check (e.g. ['read', 'change']), and app is the application name as a string. To do the same check as has_perm above you'd call something like this:

result = has_model_permissions( myuser, mycar, ['read'], 'drivers' )

If you need to use object or row permissions (they mean the same thing), then Django can't really help you by itself. The nice thing is that you can use both model and object permissions side-by-side. If you want object permissions you'll have to either write your own (if using 1.2+) or find a project someone else has written, one I like is django-objectpermissions from washingtontimes.

Alex Kuhl
  • 1,814
  • 1
  • 13
  • 19
  • 32
    This is a great answer for permissions, but barely touches groups and how they work in Django? – NotSimon Jul 22 '13 at 22:53
  • 5
    There isn't a whole lot to groups, they're mostly just for bundling users together to apply permissions, much like Linux user groups. You give a permission to a Group and it extends to all members of that group. The documentation says it all really: https://docs.djangoproject.com/en/dev/topics/auth/default/#groups. – Alex Kuhl Jul 24 '13 at 00:01
  • Looks like Django Advent is gone, there's a version of the article about writing your own object permissions on Github: https://github.com/djangoadvent/djangoadvent-articles/blob/master/1.2/06_object-permissions.rst – Mick T Feb 17 '14 at 19:02
  • 1
    I feel compelled to point out here that you want to consider using [django guardian](https://github.com/lukaszb/django-guardian) for this. See the [authorization package breakdown](https://www.djangopackages.com/grids/g/authorization/) here. Also this [SOF link](http://stackoverflow.com/questions/11082564/django-object-permissions-vs-django-guardian-vs-django-authority) provides a nice comparison. – Jeff Sheffield Aug 04 '14 at 18:12
  • 1
    As I came across this and needed object permission I found django-guardian: http://django-guardian.readthedocs.org/en/v1.2/ – dArignac Nov 03 '14 at 07:08
  • If you use model.__name__ in entity.has_perm, you have to convert the model name to lower case. – kloddant Jun 08 '17 at 18:25
  • 1
    The 'write your own' is down. Or something. It's in Chinese now. – William Karlsson Jun 21 '18 at 12:23