Django: вернуть несколько просмотров с одного URL без перенаправления

С представлением Django на основе функций было просто переключаться между несколькими различными представлениями в зависимости от условия, например. что-то типа:

def base_view(request):
    if some_condition():
        return foo_view(request)
    else:
        return bar_view(request)

Я не могу найти простой способ сделать то же самое с новыми универсальными представлениями на основе классов. Единственный способ, о котором я могу думать, - это перенаправить, чего я хотел бы избежать по разным причинам:

def base_view(request):
    if some_condition():
        return redirect(reverse("name_of_url_to_class-based_view_foo"))
    else:
        return redirect("/url_to_class-based_view_bar/")

Какие-либо предложения?


person Berislav Lopac    schedule 22.05.2011    source источник


Ответы (2)


Это эквивалентно вашему примеру с представлениями на основе классов.

class FooView(View):
    pass

class BarView(View):
    pass

class BaseView(View):
    # staticmethod to avoid adding 'self' to the arguments
    foo_view = staticmethod(FooView.as_view())
    bar_view = staticmethod(BarView.as_view())

    def dispatch(self, request, *args, **kwargs):
        if some_condition():
            return self.foo_view(request, *args, **kwargs)
        else:
            return self.bar_view(request, *args, **kwargs)
person Michał Modzelewski    schedule 22.05.2011

Хотя в документах Django говорится, что функция основана на общих представлениях теперь устарели Я думаю, что единственная причина для перехода будет заключаться в том, что вы пишете меньше кода.

Если вы все еще настроены на переключение, вам нужно сначала определить, какие представления или миксины на основе классов являются наиболее подходящими (один объект, несколько объектов, на основе даты, формы и т. д.). Если условное выражение использовалось для выбора функции, которая возвращает другие контекстные данные/шаблон для предоставления представлению, вы можете переместить условное выражение в переопределенное get_queryset|get_context_data|get_object|get_template_names в зависимости от вашего варианта использования.

Например,

def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context
    context = super(BaseView, self).get_context_data(**kwargs)
    # Add in the publisher
    if some_condition():
        context['some_data'] = ...
    else:
        context['other_data'] = ...
    return context

Если ничего не помогает, и вы по-прежнему полны решимости иметь представления на основе классов, вы, вероятно, могли бы также переопределить get(self, request, *args, **kwargs) и переключиться на соответствующий метод. подробная документация становится лучше, но я все еще нашел я копаюсь в исходном коде, чтобы понять, как добиться того, чего я хочу.

person A Lee    schedule 22.05.2011