Django FrameworkРазные варианты отображения для одних и тех же данных

Опыт "забавностей" становится всё больше и больше. Вот очередной случай маразма. Коротко суть:
Существует сайт, на котором нужно выводить одни и те же объекты с разными условиями выборки (по категории, по тегу, "захабареные" и т.п.) и разными отображениями (список, подробно и т.п.).
Некоторые индивиды, создают в каждом view замысловатую структуру из if-ов, и каждый раз она повторяется. Запомните:
  1. Рефакторинг
  2. Рефакторинг
  3. Рефакторинг
  4. view — это просто функция!
И так, по последнему пункту. Многие не понимают, что view это всего-лишь функция, возвращающая HttpResponse и не более, поэтому куда грамотнее выделить специфичные для конкретного отображения действия, да и вообще выбор отображения в отдельную функцию. Это легко делается вызовом в конце основного вида:
return extra_view(request, objects=myobjects)
Для полноты восприятия, приведу код по-больше.
def list(request):
    """
    Выводит списко всех объектов
    """
    myset = MyDataObject.objects.all()
    return extra_view(request, myset)
def category(request, category_id):
    """
    Выводит список объектов по категории
    """
    category = get_object_or_404(Category, pk=category_id)
    myset = MyDataObject.objects.filter(category=category)
    return extra_view(request, myset)
def extra_view(request, object_set):
    """
    Обёртка
    """
    view_type = request.GET.get('view_type', 'list')
    return render_to_response('view_type/%s.html' % view_type', {'objects': object_set}
Это крайне простой пример (извините, немного лень писать больше, а рабочий код, по понятным причинам, показать не могу). У меня же ещё навешаны: сортировка, выборка по дате и пр. Замечу, что можно легко использовать декораторы, и тогда немного поменяется всё, но это мелочи (вместо того, чтобы возвращать extra_view, функция будет возвращать просто object_set; мне просто более понятен представленный подход)

P.S> Помните об эффективности и красоте кода, это крайне важно.
P.P.S> Конечно, это статья скорее о рефакторинге и MVC, но встречаю данную ошибку чаще всего в django проектах, уж не знаю почему.

комментарии (4)

  • Кажется в данном примере как раз данные разные, а отображение одно и то-же.
    Под разными данными я понимаю содержимое, а не форму. Форма у данных одна и таже.
    Посему: что мешает оставлять один и тот-же вид, а в котроллере отлавливать параметры сортировки?
    • Да, нестыковочка) Там по сути и отображение и данные разные. Я немного неверно (неполно?) изложил свою мысль. Тут и шаблон разный и данные. Проблема в том, что если бы данные были одинаковыми, то смысла в нагромождении небыло бы... Да, с одной стороны правильный вынос функционала в отдельную функцию на будущее. Но это бессмысленно.

      Суть в том, что в extra_view мы получаем одни и те же данные в плане их структуры, а вот отображаем в зависимости от потребностей пользователя.

      Приведу для примера свой код, всё же.

      def video_list(request, object_set=Video.objects.all(), tpl_add={}):
      """
      Все списки пропускать через эту херню, классический упрощённый, либо класический вид
      и т.п. на основе request. Итого:
      * Учитывает какой тип представления выбрал пользователь
      * Учитывает сортировку, если указано
      * Делает выборку по дате
      """
      view_type = request.GET.get('view', 'classic')
      time_type = request.GET.get('time', 'all')
      show_type = request.GET.get('show', 'new')
      object_set = object_set.order_by('-add_date')

      object_set = add_time_filter(time_type, object_set)

      return render_to_response('catalog/%s.html' % view_type,
      RequestContext(request, {'videos': object_set,
      'view_type': view_type,
      'time_type': time_type,
      'show_type': show_type,
      'tpl_add': tpl_add}))
  • Я в последнее время частенько в качестве extra_view использую generic views - большая часть вьюх так или иначе к ним сводится.
  • P.S> Помните об эффективности и красоте кода, это крайне важно.

    Как бы это доходчиво другим обьяснить?
Только авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.