Как перенаправить ListView в DetailView, если набор запросов — это один объект?

#django

#django

Вопрос:

У меня есть ListView с пользовательским методом get_queryset () и DetailView, но я хотел бы избежать отображения ListView, когда набор запросов возвращает только один объект (я хочу перенаправить пользователя на DetailView этого объекта).

Есть ли способ добиться этого, используя представления на основе классов? Я попытался перенаправить внутри get_queryset() ListView, но это не работает, и я не могу найти ничего полезного в документации по классу ListView.

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

1. Это противоречит цели restful API. Почему вы хотите это сделать?

2. У меня есть форма, в которой пользователь может искать объекты по их имени или его части. Если пользователь выполняет поиск по части имени и возвращается более одного результата, я хочу показать им ListView, но если пользователь ищет точное имя, я хочу перенаправить их непосредственно на DetailView объекта.

3. Я думаю, что логика на стороне клиента должна обрабатываться с использованием представления списка или подробного представления. Сервер не должен знать об этом.

Ответ №1:

Вы должны вызвать redirect внутри get :

 from django.shortcuts import redirect
from django.views.generic import ListView

class MyListView(ListView):
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset() 
        if queryset.count() == 1:
            return redirect('your_detail_view_url', pk=queryset.first().pk)
        return super().get(request, *args, **kwargs)
  

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

1. Спасибо, это именно то, что я искал, но мне пришлось его немного изменить: queryset.count() требуется один обязательный параметр, объект, который я хочу учитывать в списке, поэтому я использовал len(queryset) .

Ответ №2:

Я немного изменил ответ Ивана (использование count() метода было неправильным, и мне также нужно использовать slug вместо pk для моего DetailView), поэтому решение было:

 from django.shortcuts import redirect
from django.views.generic import ListView

class MyListView(ListView):
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset() 
        if len(queryset) == 1:
            return redirect('your_detail_view_url', queryset.first().pk)
        return super().get(request, *args, **kwargs)