DjangoからのXML応答にBOMを追加する
-
07-07-2019 - |
質問
Djangoの render_to_response
を使用してXMLドキュメントを返します。この特定のXMLドキュメントは、フラッシュベースのチャートライブラリを対象としています。ライブラリでは、XMLドキュメントがBOM(バイトオーダーマーカー)で始まる必要があります。 Djangoが応答に対するBOMを前悔させるにはどうすればよいですか?
BOMをテンプレートに挿入することはできますが、ファイルを編集するたびにEmacsが削除するので不便です。
次のように 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)
解決
UTF-8にはBOMがないため、実際にはBOM(バイトオーダーマーク)について話しているのではありません。サンプルコードから、ライブラリは、説明できない理由でテキストの先頭に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
現在、特定の応答にBOMを追加するために、 render_to_response(" foo.xml&quot ;, mimetype =" text / xml&quot ;, bom = True)
を実行できます。 p>
最も簡単なことは、BOMを削除しないようにEmacsを構成することです。
しかし、render_to_responseは複雑な関数ではありません。基本的には:
def render_to_response(*args, **kwargs):
return HttpResponse(loader.render_to_string(*args, **kwargs))
render_to_stringを簡単に呼び出してBOMを追加できます。