Работа программно с HTTPResponse в Django - PullRequest
1 голос
/ 07 августа 2010

Я работаю над приложением, которое включит функцию предварительного просмотра для модели.Модели, помеченные как способные к предварительному просмотру, позволят вносить изменения в интерфейс администратора Django и предварительно просматривать на сайте, используя то же представление, что и объект этого типа, обычно используемый для визуализации, но визуализируемый вместо этого с помощьюновый (несохраненный) объект на своем месте.

Это довольно простая задача, которую можно выполнить на заказ, если вы заранее знаете представления или шаблоны.Но я хочу, чтобы это было многократно и просто.

Что я думал

Моя идея состоит в том, чтобы применить функцию resol () urls к существующим (сохраненным)значение get_absolute_url() объекта для обнаружения динамически используемого представления.Затем вызовите это представление, получите возвращенный HTTPResponse и измените его каким-либо образом, прежде чем возвращать его сам.

Проблема

Кажется, что к тому времени, когда HTTPResponse возвращаетсяЕстественное представление объекта: HTML уже отрисован механизмом шаблонов.

Так что я думаю, вопрос в следующем: Есть ли способ получить HTTPResponse до визуализации шаблона и изменить переменные контекста до того, какэто происходит .

Если нет, то может ли та же идея быть реализована другим способом.Может ли использование промежуточного программного обеспечения что-то изменить (вы все еще работаете с HTTPResponse объектом).

Спасибо,

Маркус

PS Если вы столкнетесь с радикально другимМетодология решения этой проблемы, я обязательно приписываю вам эту концепцию в документации приложения (несмотря на то, что сейчас это небольшое приложение).

1 Ответ

1 голос
/ 07 августа 2010

Это нетривиально невозможно, нет, проще всего было бы на самом деле написать собственный обработчик контекста шаблона , который проверяет, например, установлено ли что-то вроде GET['preview'], затем устанавливает значения словаря на основе некоторых других ПОЛУЧИТЬ или ПОСТИТЬ данные. Кроме того, при добавлении других переменных следует убедиться, что они не перезаписывают существующие значения, установленные этим методом (в противном случае представление переопределит его в любом случае с некоторыми другими данными).

Однако, одно замечание: совершенно ненавязчивое поведение часто приводит к ошибочному поведению. Если представление не знает об этой функции предварительного просмотра и, например, он ожидает действительный идентификатор или перенаправляет на страницу ошибки, ваш предварительный просмотр не будет работать (так как у вас нет действительного идентификатора). Выбор представлений, которые знают об этой функции предварительного просмотра, действительно является дополнительной работой, но, безусловно, будет правильным. Вы можете попытаться сделать его более универсальным, используя декораторы или вызываемые классы представления (которые могут быть получены из некоторой общей базы) вместо методов представления.

Совершенно другой подход, который лишь немного «нагляден», я предполагаю, что вы не хотите сохранять модель, чтобы она не отображалась в общедоступных списках. Подход может состоять в том, чтобы добавить поле «предварительного просмотра» и использовать менеджеры для ограничения поиска, поэтому что-то вроде этого:

класс NoPreviewManager (models.Manager): def get_query_set (self): вернуть супер (MyModelManager, self) .get_query_set (). filter (preview = False)

класс MyModel (models.Model): ... # другие поля preview = models.BooleanField ()

objects = NoPreviewManager()
allobjects = models.Manager()

Во всех обычных представлениях вы можете просто использовать MyModel.objects, чтобы превью не отображалось. В объектно-ориентированном представлении вы используете MyModel.allobjects, чтобы также включить по умолчанию предварительные просмотры. Таким образом, вам не нужно совершать странные представления, угоняющие вещи, но вы должны позаботиться о том, чтобы объекты предварительного просмотра были очищены, если они не превращены в реальные объекты. Обратите внимание, что вы также можете объединить многие из этой логики в базовый класс.

...