Промежуточное ПО Django для определения группы пользователя в сеансе

У меня есть приложение, которое использует django.contrib.auth, но не использует встроенную систему разрешений Django. Вместо этого представления имеют декоратор @login_required, а затем проверяют, к какой группе принадлежит пользователь, и следят за различными ветвями выполнения кода в представлении в зависимости от группы.

Пользователь может принадлежать только к одной группе.

Проверка группы пользователя каждый раз кажется слишком сложной, поэтому я пытаюсь написать промежуточное программное обеспечение Django, которое позволит мне узнать группу пользователя в сеансе.

Глядя на приведенный ниже код, будет ли мое промежуточное ПО работать так, как я хочу?

class SetGroupMiddleware(object):
    def process_request(self, request):
        check_if_already_set = request.session.get('thegroup', 'notset')
        if check_if_already_set == 'notset':
            if request.user.id: # User is not AnonymousUser
                groups = request.user.groups.all()
                if groups: # actually this will always be True
                    request.session['thegroup'] = str(groups[0].name) # flowchart of the app ensures that the logged in user will only have one group, and that the user will always have a group
            else:
                request.session['thegroup'] = 'nogroup' # for completeness

Затем я намерен проверить request.session['thegroup'] там, где это необходимо.

Нужны ваши предложения и мнения. Безопасен ли сеанс, если он обрабатывается таким образом? Будет ли это работать вообще? Я новичок в Django, Python и программировании в целом.

Спасибо.


person gbsmith    schedule 11.12.2009    source источник


Ответы (3)


В целом выглядит хорошо. Однако вы можете сделать его немного более Pythonic:

class SetGroupMiddleware(object):
    def process_request(self, request):
        if 'thegroup' not in request.session:
            if not request.user.is_anonymous():
                groups = request.user.groups.all()
                if groups:
                    request.session['thegroup'] = str(groups[0].name)
            else:
                request.session['thegroup'] = None # for completeness
person Steve Losh    schedule 11.12.2009
comment
Ответ Питера Роуэлла о порядке промежуточного программного обеспечения был очень важен, но я собираюсь отметить ваш ответ как принятый ответ из-за того, как вы улучшили мой (очевидно, новичок) код. - person gbsmith; 12.12.2009
comment
Ну, если пользователь начинает как анонимный (что в большинстве случаев так и есть), то с текущим кодом request.session['thegroup'] не обновляется при входе в систему. Я постараюсь отладить это, и если смогу, я опубликую это здесь. - person gbsmith; 14.12.2009

Выглядит примерно правильно (не тестировал). Следует отметить, что промежуточное ПО должно находиться после django.contrib.sessions.middleware.SessionMiddleware в списке MIDDLEWARE_CLASSES, иначе сеанс не будет настроен для вас в то время, когда вы пытаетесь сослаться на него.

person Peter Rowell    schedule 11.12.2009
comment
Итак, если это произойдет после SessioonMiddleware, нужно ли мне явно помечать сеанс как грязный? Или структура сеанса обнаружит и сохранит эту информацию автоматически? - person gbsmith; 11.12.2009
comment
Поскольку вы изменяете сеанс напрямую, вам не нужно явно сохранять его. См.: http://docs.djangoproject.com/en/dev/topics/http/sessions/#when-sessions-are-saved - person Steve Losh; 11.12.2009

Ну, как я прокомментировал в ответ Стива Лоша этот код не работает должным образом.

Я изменил его следующим образом, и до сих пор все в порядке: -

class SetGroupMiddleware(object):
    def process_request(self, request):
        if not request.user.is_anonymous():
            if 'thegroup' not in request.session:
                groups = request.user.groups.all()
                if groups:
                    request.session['thegroup'] = str(groups[0].name)
person gbsmith    schedule 14.12.2009