2

Djangoを使用render_to_responseしてXMLドキュメントを返します。この特定のXMLドキュメントは、フラッシュベースのチャートライブラリを対象としています。ライブラリでは、XMLドキュメントがBOM(バイト順マーカー)で始まる必要があります。DjangoにBOMを応答にプリペントさせるにはどうすればよいですか?

BOMをテンプレートに挿入することはできますが、ファイルを編集するたびにEmacsがBOMを削除するため、不便です。

次のように書き直そうとしましrender_to_responseたが、BOMが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)
4

3 に答える 3

2

UTF-8 には BOM がないため、実際には BOM (バイト オーダー マーク) について話しているわけではありません。サンプルコードから、ライブラリは、テキストの前に3バイトのガベージバイトが追加されることを予期しています。

コードはほぼ正しいですが、バイトを文字ではなく bytes として先頭に追加する必要があります。これを試して:

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)
于 2009-09-14T21:13:17.767 に答える
1

John Millikinの回答の以前のバージョンに基づくこのソリューションは、私が受け入れたものよりも複雑ですが、完全を期すためにここに含めています。まず、ミドルウェアクラスを定義します。

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)これで、特定の応答の前にBOMを追加することができます。

于 2009-09-14T21:38:59.150 に答える
0

最も簡単な方法は、BOM を削除しないように Emacs を構成することです。

しかし、render_to_response は複雑な関数ではありません。基本的には次のとおりです。

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

簡単に render_to_string を呼び出して、BOM を先頭に追加できます。

于 2009-09-14T21:09:49.003 に答える