Search code examples
djangosettingsdjango-permissions

Django app for user/account settings


Im prepping for developing one project and am in process of mapping out stuff i can use for it. This project is going to need different group/user based model & object permissions and settings.

I know i can use django-objectpermissions (https://github.com/washingtontimes/django-objectpermissions) and djangos own model permissions. But there are some cases, when you dont really need to set object/model permissions, but rather a setting - can this account/user do something, which is not related to certain object or model. Has someone developed app for this? Or what kind of approach do people take when they have such need? Perhaps create dummy django model and let djangos model permissions handle the rest?

I also know, that this does something similar - https://github.com/danielroseman/django-dbsettings. But when i skimmed through the code i got impression, that those settings are all user based - i need also group based settings.

Edit: People keep offering me permissions apps. What i am looking for is not permissions app, but settings app. Those settings/permissions are not related to any objects.

Basically. In my project i need to answer questions - Can this user see/do this thing?. That "thing" is most likely a view. So one of the answers almost works. But the check i do at view, is not if user has permission to some model/object. Its rather, if the user has this setting turned on, of if users group has this setting turned on.

Alan


Solution

  • You're probably going to need to create your own system for this. It shouldn't be very difficult.

    class Setting(models.Model):
        name = models.CharField(..)
        value = models.CharField(..)
        users = models.ManyToManyField(User)
        groups = models.ManyToManyField(Group)
    
        @classmethod
        def has_setting(cls, name, user):
            user_settings = cls.objects.filter(name=name, users__in=[user]).count()
            group_settings = cls.objects.filter(name=name, groups__in=user.groups.all()).count()
            return user_settings or group_settings
    
        @classmethod
        def get_settings(cls, name, user, priority=User):
            user_settings = list(cls.objects.filter(name=name, users__in=[user]))
            group_settings = list(cls.objects.filter(name=name, groups__in=user.groups.all()))
            if user_settings and not group_settings: 
                return user_settings
            elif group_settings and not user_settings:
                return group_settings
            else:
                return (group_settings, user_settings)[priority==User]
    

    Then you can do something like this in your views:

    def display_frob(request):
        if Setting.has_setting('display_frob', request.user):
             settings = Setting.get_setting('display_from', request.user, priority=Group)
             values = [setting.value for setting in settings]
             # if the User was in many groups, we now have a list of values, for the setting
             # `display_frob`, that aligns with each of those groups
    

    You can easy build a decorator which will do the check, and provide a list (or a single item) of values to the view.