Frage

Ich verwende Django render_to_response ein XML-Dokument zurückzukehren. Dieses besondere XML-Dokument wird für eine Flash-basierte Charting-Bibliothek bestimmt. Die Bibliothek setzt voraus, dass das XML-Dokument mit einer BOM (Byte Order Marker) starten. Wie kann ich Django die BOM auf die Antwort prepent?

Es funktioniert die Stückliste in die Vorlage einfügen, aber es ist unbequem, weil Emacs es jedes Mal entfernt ich die Datei bearbeiten.

Ich habe versucht, render_to_response zu umschreiben wie folgt, aber es funktioniert nicht, weil die Stückliste wird UTF-8 codiert:

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)
War es hilfreich?

Lösung

Sie sprechen nicht wirklich über eine BOM (Byte Order Mark), da UTF-8 keine BOM haben. Von Ihrem Beispiel-Code, erwartet, dass die Bibliothek des Text 3 Müll Bytes aus unerklärlichen Gründen vorangestellt haben.

Der Code ist fast richtig, aber Sie müssen die Bytes vorangestellt als Bytes , nicht Zeichen. Versuchen Sie folgendes:

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)

Andere Tipps

Diese Lösung basiert auf einer früheren Version von John Millikin Antwort ist komplexer als das, was ich akzeptiert, aber ich bin auch hier der Vollständigkeit halber. Zunächst definiert eine Middleware-Klasse:

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

Fügen Sie ihren Namen in MIDDLEWARE_CLASSES in Ihren Einstellungen. Dann render_to_response neu zu definieren:

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

Jetzt können Sie render_to_response("foo.xml", mimetype="text/xml", bom=True) tun, um die Stückliste auf eine bestimmte Reaktion auf voranstellen.

Die einfachste Sache sein könnte Emacs konfigurieren nicht die Stückliste zu entfernen.

Aber render_to_response ist nicht eine komplizierte Funktion. Es ist im Grunde:

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

Sie könnten leicht render_to_string nennen und die Stückliste vorangestellt wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top