2009-09-14 5 views
2

J'utilise le render_to_response de Django pour renvoyer un document XML. Ce document XML particulier est destiné à une bibliothèque de graphiques Flash. La bibliothèque nécessite que le document XML commence par une BOM (marqueur d'ordre des octets). Comment puis-je faire en sorte que Django prépasse la nomenclature à la réponse?Ajoute la réponse BOM à XML de Django

Cela fonctionne pour insérer la nomenclature dans le modèle, mais ce n'est pas pratique car Emacs le supprime chaque fois que j'édite le fichier.

J'ai essayé de réécrire render_to_response comme suit, mais il échoue parce que la nomenclature est en cours de codage 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) 

Répondre

2

Vous ne parlez pas vraiment d'une nomenclature (BOM), car l'UTF-8 n'a pas de nomenclature. À partir de votre exemple de code, la bibliothèque s'attend à ce que 3 octets d'ordures soient ajoutés au texte pour une raison inexplicable.

Votre code est presque correct, mais vous devez préfixer les octets comme octets, pas les caractères. Essayez ceci:

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) 
+0

J'imagine que c'est * UTF-8 dont nous parlons. Certains logiciels (typiquement dérivés de Microsoft) aiment mettre les nomenclatures en UTF-8 en dépit de leur inutilité et de leur nocivité. Un lecteur XML qui en nécessite un, cependant, il cassé et pas vraiment un lecteur XML du tout. – bobince

+0

Il n'y a pas de nomenclature en UTF-8, car UTF-8 n'a pas d'ordre d'octets. Si certains logiciels dépendent de la présence d'octets aléatoires dans un fichier, c'est quelque chose de différent. –

+0

@Vebjorn: J'ai mis à jour la réponse pour refléter votre question éditée. Votre code est presque déjà correct. –

0

La chose la plus simple est peut-être configurer Emacs de ne pas supprimer la nomenclature.

Mais render_to_response n'est pas une fonction compliquée. Il s'agit essentiellement:

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

Vous pouvez facilement appeler render_to_string et ajouter un préfixe à la nomenclature.

1

Cette solution, basée sur une version antérieure de la réponse de John Millikin, est plus complexe que celui que j'accepté, mais je suis ici, y compris pour l'exhaustivité. Tout d'abord, définissez une classe de middleware:

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 

Ajoutez son nom à MIDDLEWARE_CLASSES dans vos paramètres. Puis redéfinir 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 

Maintenant, vous pouvez faire render_to_response("foo.xml", mimetype="text/xml", bom=True) pour préfixer la nomenclature à une réponse particulière.

Questions connexes