Разрешение URL-адресов в разных представлениях для разных типов профилей пользователей в Django - PullRequest
2 голосов
/ 09 июля 2011

Я добавляю новый тип профиля пользователя на сайт, и этот новый тип пользователя (скажем, new_type) не должен иметь возможности достичь тех же взглядов, что и существующие пользователи.

Мой вопрос: какМогу ли я использовать различные типы представлений в соответствии с типом пользователя, используя одни и те же пути запроса, не изменяя существующие коды представлений, например добавляя

if user.profile_type == 'blah':
    do_this 
else: 
    do_that 

к каждому представлению?

Подробно:

Я хотел бы использовать «http://mysite.com/path/" для обоих типов пользователей, используя разные логики и возвращая разные дисплеи, не внося различий в существующие представления (поскольку существует множество представлений для изменения).

I 'Я думаю о добавлении различных групп представлений для нового типа, а затем переопределить логику URL для разрешения путей запросов к соответствующим представлениям, например:

if user is of new_type 
    resolve path to related_view_for_new_type
else
    resolve as usual 

В качестве прямого примера: вход в систему с правами администратора и обычного пользователя изтот же URL-адрес входа в систему, и если пользователь является администратором, запустите соответствующие представления для администратора и верните ей отображение администратора django, если это обычный пользователь, затем запустите обычное представлениеи верните ей обычный вид веб-сайта, не переписывая и не изменяя URL-адрес, который они запрашивают.(/ index / например)

Можно ли таким образом расширять URL-адреса в Django и если да, то как, или я должен отказаться от перегрузки тех же путей запроса и добавить '/ new_type /' к URL-адресам (http://mysite.com/new_type/path/)for новых пользователей типа?

Спасибо

Ответы [ 3 ]

2 голосов
/ 09 июля 2011

Для начала, что значит иметь разных типов пользователей? Очень простой способ сделать это - сохранить атрибут у пользователя. Таким образом, при наличии объекта user вы можете посмотреть на этот дополнительный атрибут, чтобы определить, относится ли пользователь к специальному типу. Django имеет стандартный механизм хранения дополнительных атрибутов, таких как этот, о котором вы можете прочитать здесь .

Если у вас есть способ определения пользовательских типов, вы можете создать один декоратор и применить его к любому представлению, которое должно вести себя так, как вы описали. Декораторы - отличный способ применения дополнительных условий или поведения к существующим функциям. Логика в декораторе начинает работать до и / или после существующей функции, поэтому она может очень легко выполнить что-то вроде отображения другого шаблона в зависимости от типа пользователя.

Функции декоратора выглядят очень странно, когда вы впервые сталкиваетесь с ними, но прочитайте их внимательно, и вы скоро получите их. Декоратор - это сама функция, и вы даете ей функцию, которую хотите декорировать. Он возвращает вам новую функцию, которая является вашей старой функцией, обернутой дополнительной логикой.

Я написал несколько непроверенных примеров кода ниже.

def template_based_on_user_type(special_template, ordinary_template):
    def decorator(your_view_function):
        def inner_decorator(request, *args, **kwargs):
            # this is the logic that checks the user type before 
            # every invocation of this view:
            if request.user.type == 'special_type':
                template = special_template
            else:
                template = ordinary_template

            # this is the invocation of the view function, with
            # a custom template selected:
            return your_view_function(request, template)
        return inner_decorator
    return decorator

@template_based_on_user_type('my-special-template.html', 'ordinary-template.html')
def my_view_function(request, template='default.html'):
    # Do what you need to do here
    render_to_response(template, data, RequestContext(request)

Синтаксис для применения декоратора - символ «@», за которым следует функция декоратора. Декоратор настраивается с указанными именами шаблонов.

0 голосов
/ 20 января 2017

Я решил эту проблему с помощью декоратора в urls.py:

def dispatch_by_user(staff_view, external_user_view):
    def get_view(request, **kwargs):
        if (is_staff_user(request.user)):
            return staff_view(request, **kwargs)
        else:
            return external_user_view(request, **kwargs)
    return login_required(get_view)

def is_staff_user(user):
    return user.groups.filter(name="privileged-group").exists()

Итак, шаблоны установлены следующим образом:

urlpatterns = [
    url(r'^$',
        dispatch_by_user(
                views.StaffHomeView.as_view(),  
                views.ExternalUserClientView.as_view()),
        name='index'),
     # ...
]
0 голосов
/ 09 июля 2011

RTFM как обычно:)

Вот ссылка на возможное решение: method_splitter @ http://www.djangobook.com/en/2.0/chapter08/

Имена новых связанных типов будут получены из оригиналов путем добавления new_type_в начале имени, такого как index-> ​​new_type_index

, тогда я определю возвращаемое представление, просто проверив атрибут request.user.is_new_type.некрасиво, но лучше, чем модификация миллиардов просмотров.

...