Вопрос

Я использую render_to_response Джанго для возврата XML-документа. Этот конкретный документ XML предназначен для библиотеки диаграмм на основе флэш-памяти. Библиотека требует, чтобы документ XML начинался с спецификации (маркера порядка байтов). Как я могу заставить Django подготовить спецификацию к ответу?

Он работает для вставки спецификации в шаблон, но это неудобно, потому что Emacs удаляет ее каждый раз, когда я редактирую файл.

Я попытался переписать render_to_response следующим образом, но это не удалось, потому что спецификация кодируется в UTF-8:

def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    s = django.template.loader.render_to_string(*args, **kwargs)
    if bom:
        s = u'\xef\xbb\xbf' + s
    return HttpResponse(s, **httpresponse_kwargs)
Это было полезно?

Решение

Вы на самом деле не говорите о спецификации (метке порядка байтов), поскольку в UTF-8 нет спецификации. Исходя из вашего примера кода, библиотека ожидает, что в тексте будет добавлено 3 байта мусора по какой-то необъяснимой причине.

Ваш код почти верен, но вы должны добавлять байты в виде байтов , а не символов. Попробуйте это:

def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    s = django.template.loader.render_to_string(*args, **kwargs)
    if bom:
        s = '\xef\xbb\xbf' + s.encode("utf-8")
    return HttpResponse(s, **httpresponse_kwargs)

Другие советы

Это решение, основанное на предыдущей версии ответа Джона Милликина, является более сложным, чем то, которое я принял, но я привожу его здесь для полноты. Сначала определите класс промежуточного программного обеспечения:

class AddBOMMiddleware(object):
    def process_response(self, request, response):
        import codecs
        if getattr(response, 'bom', False):
            response.content = codecs.BOM_UTF8 + response.content
        return response

Добавьте его имя в MIDDLEWARE_CLASSES в ваших настройках. Затем переопределите render_to_response :

def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    rendered = django.template.loader.render_to_string(*args, **kwargs)
    response = django.http.HttpResponse(rendered, **httpresponse_kwargs)
    if bom:
        response.bom = True
    return response

Теперь можно выполнить render_to_response (" foo.xml " ;, mimetype = " text / xml " ;, bom = True) , чтобы добавить спецификацию к конкретному ответу.

Проще всего настроить Emacs так, чтобы он не удалял спецификацию.

Но render_to_response не сложная функция. Это в основном:

def render_to_response(*args, **kwargs):
    return HttpResponse(loader.render_to_string(*args, **kwargs))

Вы могли бы легко вызвать render_to_string и добавить к нему спецификацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top