перенаправление django на другой вид/страницу, если в разрешении отказано

#django #django-views #django-authentication #django-permissions

Вопрос:

Хей!

У меня есть представление, в котором отображаются контактные данные. Цель состоит в том, чтобы некоторые пользователи могли видеть все детали («A»), а некоторые-только имя («B»). Поэтому у меня есть два сериализатора в моей модели и два представления (по одному для каждого сериализатора). Пользователи разделены на две группы.

Это @user_passes_test работает так, что только тот, кто входит в группу «А», может попасть в представление с подробностями.

Я хочу, чтобы те, которые находятся в группе «B», автоматически перенаправлялись на просмотр/страницу, где сведения сведены к минимуму.

Есть идеи, как этого добиться?

У меня есть:

 # views.py
def contacts_check(user):
   return user.groups.filter(name="Contacts = True").exists()


@login_required
@user_passes_test(contacts_check)
def contacts(request):
   .
   .
   .


@login_required
def contacts_small(request):
   .
   .
   .
 
 # urls.py


app_name = "app"
urlpatterns = [
    path("contacts", contacts, name="contacts"),
    path("contacts2", contacts_small, name='contacts2')
]
 

Я пытался:

 @user_passes_test(contacts_check, login_url='contacts')
 

но обе группы пользователей перенаправлены на URL-адрес «контакты» с полным представлением. («B» получает сообщение об ошибке, что у пользователя нет доступа). То же самое, когда login_url=’контакты 2′.

Я тоже пытался:

 def sees_contacts(self):
   if str(self.user.groups.filter) == 'Contacts = True':
       return True
   else:
       return False
con_login_required = user_passes_test(lambda u: True if u.sees_individuals else False, login_url='individuals2')


def contacts_login_required(view_func):
   decorated_view_func = login_required(con_login_required(view_func), login_url='contacts2')
   return decorated_view_func
 

не фильтрует/не перенаправляет должным образом.

 # views.py 
def contacts_check(user):
   return user.groups.filter(name="Contacts= True").exists()


def contacts_view(request):
   if contacts_check():
       return search_contacts(request)
   return search_contacts_small(request)

@login_required
def search_contacts(request):
   ....


@login_required
def search_contacts_small(request):
   ....
 

У кого-нибудь есть идеи, что я делаю не так?

Ответ №1:

В urls.py просто используйте один путь

 path("contacts/", contacts_view, name="contacts-view"),
 

затем в методе

 def contacts_view(request):
    if sees_contacts():
        return contacts(request)
    return contacts_small(request)
 

Это поможет сделать шаблоны URL менее запутанными для вас и пользователей и позволит вам легко разделять представления.

Комментарии:

1. это выглядит идеально! Я создал метод, который вы предложили, но теперь получаю ошибку: Reverse for 'contacts' not found. 'contacts' is not a valid view function or pattern name. Вы знаете, что происходит не так?

2. вам нужно поменять местами «контакты-просмотр», если вы использовали мой код

3. Чем ошибка» contacts_check() отсутствует 1 требуемый позиционный аргумент: «пользователь» Должен ли я изменить свой чек, чтобы получить его не через декоратор, а внутри метода?

4. Если () contacts_check(): удалены, ошибка больше не возникает, но и не будет фильтроваться.

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