Как передать много параметров для просмотра в Django? - PullRequest
4 голосов
/ 27 апреля 2010

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

Мой просмотр страницы извлекает большие объемы данных из базы данных и помещает их в контекст. Затем шаблон генерирует разные html-таблицы. Пока все хорошо.
Теперь я хочу добавить различные диаграммы в шаблон. Мне удается это сделать, определив <img src=".../> tags. Диаграмма Matplotlib генерирует в моем виде диаграммы возврат через:

response=HttpResponse(content_type='image/png')
canvas.print_png(response)
return response

Теперь у меня есть разные вопросы:

  1. данные извлекаются дважды из базы данных. Один раз в просмотре страниц, чтобы отобразить таблицы, и снова в просмотре диаграмм для создания диаграмм. Каков наилучший способ передачи данных, уже в контексте страницы, в диаграмму?
  2. Мне нужно много диаграмм, каждая с разными наборами данных. Я мог бы сделать диаграмму для каждого графика, но, возможно, есть лучший способ. Как передать разные имена наборов данных в диаграмму? Некоторые диаграммы имеют 20 наборов данных, поэтому я не думаю, что передача этих параметров набора данных через URL (например: <imgm src="chart/dataset1/dataset2/.../dataset20/chart.png />) - правильный путь.
    Любой совет?

Ответы [ 2 ]

6 голосов
/ 27 апреля 2010

Нельзя передавать данные из представления страницы в представление диаграммы, поскольку они являются отдельными HTTP-запросами. У вас есть несколько вариантов:

  1. Передайте все данные в URL-адрес диаграммы. Это может показаться сумасшедшим, но это то, что Google Charts делает: http://code.google.com/apis/chart/docs/making_charts.html

  2. Сохранить данные в сеансе. Представление страницы заполняет данные в сеансе, а представление диаграммы будет использовать его для создания диаграммы.

  3. Кэшируйте ваши дБ-запросы в memcache. Поскольку страница и диаграмма будут ссылаться на один и тот же запрос, вы, вероятно, попадете в кеш. Это хорошее решение, потому что ваш график будет работать даже без предварительной обработки страницы.

  4. Просто запросите базу данных еще раз. Ваша СУБД, вероятно, имеет хорошее кеширование, производительность может быть не той проблемой, которую вы себе представляете.

Для вашего второго вопроса 20 слов в URL не кажутся такими уж сложными. Конечно, вы могли бы найти какой-то шаблон для выбранных наборов данных, чтобы вам не нужно было указывать их каждый раз, но если вам нужно, просто создайте длинные URL.

1 голос
/ 27 апреля 2010

Использование шаблонных тегов, вероятно, было бы тем путем, который я выбрал бы здесь. У меня была похожая ситуация, когда у меня была календарная информация, отображаемая несколько раз в разных форматах на одной странице. Я справился с этим путем передачи запрашиваемых данных в контекст запроса, а затем просто использовал этот набор запросов в качестве аргумента тега шаблона. В результате вы можете получить синтаксис шаблона:

View

def my_view(request, *args, **kwargs):
    yearly_sales_qs = SaleRecord.objects.filter(param=value)
    monthly_sales_qs = SalesRecord.objects.filter(param=foo)

    return render_to_response( ..., locals(), ... )

Template

{% load data_tags %}

<div class="year">
    {% render_data_table for yearly_sales_qs %}
    {% render_bar_chart for yearly_sales_qs %}
</div>

<div class="month">
    {% render_data_table for monthly_sales_qs %}
    {% render_bar_chart for monthly_sales_qs %}
</div>

Так как ты делаешь что-то подобное? Начните с просмотра документации Django на Пользовательские теги шаблонов и фильтры . Начать немного сложнее, чем остальную часть Django, но как только вы это получите, это довольно легко.

  • Начните с создания папки "templatetags" в папке вашего приложения.
  • Создайте пустой файл " init .py" в этой новой папке
  • Добавить расположение этой папки с тегами шаблона в настройку TEMPLATE_DIRS в settings.py (если ее там еще нет)

Поскольку мы будем делать несколько из них, мы можем создать тег базового шаблона, который мы унаследуем, который инкапсулирует наши основные функции ...

data_tags.py (хранится в папке templatetags)

class DataForTag(tempalte.Node):
    @classmethod
    def handle_token(cls, parser, token, template):
        tokens = token.contents.split()
        if tokens[1] != 'for':
                raise template.TemplateSyntaxError("First argument in %r must be 'for'" % tokens[0])

        if len(tokens) == 3:
            return cls(queryset=parser.compile_filter(tokens[2]), template=template)
        else:
            raise template.TemplateSyntaxError("%r tag requires 2 arguments" % tokens[0])

    def __init__(self, queryset=None, template=None):
        self.queryset = queryset
        self.template = template

    def render(self, context):
        return render_to_string(self.template, {'queryset':self.queryset})

Затем мы можем создать отдельные теги, которые будут обрабатывать все, что нам нужно ...

@register.tag
def render_bar_chart(parser, token):
    return DataForTag.handle_token(parser, token, 'data/charts/barchart.html')

@register.tag
def render_pie_chart(parser, token):
    return DataForTag.handle_token(parser, token, 'data/charts/piechart.html')    

@register.tag
def render_data_table(parser, token):
    return DataForTag.handle_token(parser, token, 'data/table.html')   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...