Django - связующее ПО взаимодействует с представлениями / шаблонами - PullRequest
7 голосов
/ 17 февраля 2009

Хорошо, это, вероятно, очень глупый вопрос, но я новичок в Python / Django, поэтому пока не могу по-настоящему обдумать его концепцию. Сейчас я пишу класс middleware для обработки некоторых вещей и хочу установить «глобальные» переменные, к которым могут обращаться мои представления и шаблоны. Каков «правильный» способ сделать это? Я подумал сделать что-то вроде этого:

middleware.py

from django.conf import settings

class BeforeFilter(object):
    def process_request(self, request):
        settings.my_var = 'Hello World'
        return None

views.py

from django.conf import settings
from django.http import HttpResponse

def myview(request):
    return HttpResponse(settings.my_var)

Хотя это работает, я не уверен, что это «путь Джанго» или «путь Питона» для этого.

Итак, мои вопросы:
1. Это правильный путь?
2. Если это правильный путь, как правильно добавлять переменные, которые можно использовать в реальном шаблоне из промежуточного программного обеспечения? Скажем, я хочу что-то оценить, и я хочу установить переменную headername как «Имя моего сайта» в промежуточном программном обеспечении, и я хочу иметь возможность делать {{ headername }} во всех шаблонах. Делая это так, как сейчас, я должен добавить headername к контексту внутри каждого представления. Есть ли способ обойти это? Я думаю что-то вроде CakePHP $this->set('headername','My Site Name');
3. Я использую класс промежуточного программного обеспечения в качестве эквивалента beforeFilter CakePHP, который запускается перед вызовом каждого представления (или контроллера в CakePHP). Это правильный способ сделать это?
4. Совершенно несвязанный, но это небольшой вопрос, каков хороший способ распечатать содержимое переменной в браузере ala print_r? Скажем, я хочу увидеть все вещи внутри request, которые передаются в представление? pprint ответ?

Ответы [ 3 ]

19 голосов
/ 17 февраля 2009
  1. Это не лучший способ. Вы можете установить my_var по запросу, а не по настройкам. Настройки являются глобальными и применяются ко всему сайту. Вы не хотите изменять его для каждого запроса. Могут быть проблемы параллелизма с несколькими запросами на обновление / чтение переменной одновременно.

  2. Чтобы получить доступ к request.my_var в ваших шаблонах, вы можете сделать {{request.my_var}} . Чтобы получить доступ к переменной запроса в вашем шаблоне, вам нужно будет добавить django.core.context_processors.request в настройку TEMPLATE_CONTEXT_PROCESSORS .

  3. Да. Другой терминологией для описания промежуточного программного обеспечения запроса будет препроцессор / фильтр / перехватчик запросов.

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

12 голосов
/ 17 февраля 2009

Вот что мы делаем. Мы используем контекстный процессор, как этот ...

def context_myApp_settings(request):
    """Insert some additional information into the template context
    from the settings.
    Specifically, the LOGOUT_URL, MEDIA_URL and BADGES settings.
    """
    from django.conf import settings
    additions = {
        'MEDIA_URL': settings.MEDIA_URL,
        'LOGOUT_URL': settings.LOGOUT_URL,
        'BADGES': settings.BADGES,
        'DJANGO_ROOT': request.META['SCRIPT_NAME'],
    }
    return additions

Здесь настройка, которая активирует это.

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
    "myapp. context_myApp_settings",
    )

Это обеспечивает "глобальную" информацию в контексте каждого шаблона, который будет представлен. Это стандартное решение Django. См. http://docs.djangoproject.com/en/dev/ref/templates/api/#ref-templates-api для получения дополнительной информации о контекстных процессорах.


"Какой хороший способ распечатать содержимое переменной в браузере ala print_r?"

По мнению? Вы можете предоставить pprint.pformat строку для шаблона, который будет отображаться в целях отладки.

В логе? Вы должны использовать модуль Python logging и отправлять данные в отдельный файл журнала. Использование простых операторов печати для записи содержимого в журнал не работает удивительно согласованно для всех реализаций Django (например, mod_python теряет все содержимое stdout и stderr.)

4 голосов
/ 17 февраля 2009

1) Если вы измените «настройки», это действительно будет глобальным даже для разных запросов. Другими словами, параллельные запросы будут вытеснять друг друга, если вам нужно, чтобы каждый запрос имел свое значение. Безопаснее модифицировать сам объект запроса, что и делает некоторое обычное промежуточное ПО Django (например, django.contrib.auth.middleware.AuthenticationMiddleware добавляет ссылку на «пользователя» в объекте запроса)

2) (РЕДАКТИРОВАТЬ 2) См. # 4, получение общего набора переменных в каждом шаблоне, вероятно, лучше подходит для процессора специального контекста

3) Я не знаком с CakePHP, но добавление промежуточного программного обеспечения process_request, безусловно, является хорошим способом Django для предварительной обработки каждого запроса.

4) Посмотрите документацию для шаблонных процессоров контекста . Если вы используете RequestContext, каждый шаблон будет иметь контекстную переменную под названием «request», которую вы можете поместить в свой шаблон. Вы также можете использовать обработчик контекста отладки и сделать что-то подобное, чтобы он выводил дамп только при настройках.DEBUG = True:

{% if debug %}
  <!-- {{ request.REQUEST }} -->
{% endif %}

Это будет работать как для GET, так и для POST, но вы можете изменить соответствующим образом, если вам нужен только один или другой.

EDIT

Кроме того, я просто присмотрелась к вашим views.py. Не уверен, что я полностью понимаю, что вы пытаетесь сделать, просто возвращая переменную в ответе. Если у вас действительно есть этот вариант использования, вы, вероятно, также захотите установить mimetype так:

return HttpResponse (..., mimetype='text/plain')

Ясно, что вы не возвращаете HTML, XML или какой-либо другой тип структурированного контента.

РЕДАКТИРОВАТЬ 2

Только что увидел, что вопрос был обновлен новым подзапросом, перенумерованы ответы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...