2010-09-30 51 views
11

Necesito escribir datos del modelo (CharField s solamente) en un archivo XML para contener los datos de un archivo flash. Soy nuevo en esto, y el proceso no me es claro por hacer esto en django. Estoy creando un archivo xml y luego escribiendo los datos de texto en el archivo (como se hace con el módulo csv, pero a xml). Un archivo XML muy simplificada debería implicar para el archivo flash para leer, es decir:Generar archivo XML a partir de los datos del modelo

<?xml version="1.0" encoding="UTF-8"?> 
<textFields> 
    <textField id="0" text="HELLO WORLD" /> 
    <textField id="1" text="HELLO EARTH" /> 
    ... 
</textFields> 

1. Estoy utilizando un serializador para escribir los datos XML del modelo:

from django.core import serializers 
data = serializers.serialize('xml', myModel.objects.filter(instanceIwantTowrite), fields=('fieldName')) 

2. Entonces crear el archivo usando core.files:

from django.core.files import File  
f = open('/path/to/new/dir/content.xml', 'w') 
myfile = File(f) 

3. Los datos de escritura de archivo y cierre:

myfile.write(data) 

myfile.close() 

Esto funciona hasta ahora, aunque la salida xml contiene los campos para el objeto "django-objects", etc., y tendré que ver si puedo interpretar esto en ActionScript fácilmente para el archivo flash. Preferiría definir los nombres de campo xml manualmente como en el módulo csv. Como soy nuevo en django y python, me pregunto si existe una forma más fácil y sencilla de hacerlo.

Nota: En serializador que use el filtro de los objetos del modelo porque el uso de get para la instancia de modelo devuelve un error object not iterable. De hecho, lo filtro dos veces para obtener una sola instancia, parece que debe haber una mejor manera.

+0

No tengo claro el formato XML que desea. ¿Es un elemento 'textField' igual a una sola fila en la base de datos, cada una con un solo campo? Si es así, ¿a qué se refiere el número 'id'? Si no, ¿cómo se diferencian entre filas? –

+0

Además, ¿ha considerado JSON como un formato de serialización? Es mucho más fácil crear y consumir. –

+0

Sí, textField sería una sola entrada de charField en el DB (cada campo de entrada de db para rellenar un campo de texto en un archivo flash). Lamentablemente, la identificación era un poco confusa, la idea es que hay varios campos de texto en el archivo flash, por lo que los id se corresponden con diferentes caracteres de caracteres en el modelo. Deben ser diferentes modelos de charFields. Estoy investigando JSON ahora, normalmente he usado xml con AS3, parece hasta ahora que JSON requeriría una importación de biblioteca AS3, y para esta aplicación eso no es una opción desafortunadamente. – HdN8

Respuesta

25

Usted tiene dos soluciones posibles aquí:

1.

Se puede extender serializador base de Django XML (django.core.serializers.xml_serializer.Serializer) y modificarlo para que vuelva datos en su estructura. Entonces podrías correr ex.

YourSerializer('xml', myModel.objects.filter(instanceIwantTowrite), fields=('fieldName')) 

y dará salida a los datos en su estructura.

2.

Escribir función simple que hará que la plantilla de su estructura de datos y devolver datos XML en su formato:

código Python

from django.template.loader import render_to_string 

def my_serialize(query_set): 
    xml = render_to_string('xml_template.xml', {'query_set': query_set}) 

    return xml 

xml_template.xml Plantilla

<?xml version="1.0" encoding="UTF-8"?> 
<textFields> 
    {% for object in query_set %} 
    <textField id="{{ object.pk }}" text="{{ object.my_field }}" /> 
    {% endfor %} 
</textFields> 
+0

Ok, la opción 2 parece ser la solución óptima para esto, por lo que puedo definir la estructura xml a voluntad usando render_to_string y una plantilla predefinida (que podría ser solo un archivo de texto, supongo). Luego solo uso el método file.write() con 'xml' como contenido ... ok genial, intentaré implementar esta opción, ¡gracias! – HdN8

+0

Sí, la plantilla es un archivo de texto. –

+0

Brillante. Funciona sin el alboroto. +1 – Glycerine

1

Para un enfoque más genérico para resolver este problema, puede evitar plantillas mediante el uso de un simple golpe de pato en Modelos y serializar cualquier gráfico de objetos profundos a XML usando ElementTree.

Así es como lo resolví: modelos de perforación parche/pato

del mono en su modelo.py como:

if hasattr(models.Model, "to_element")==False: 
    import xml.etree.ElementTree as ET 
    def to_element(self): 
     ele = ET.Element(self.__class__.__name__) 
     for field in self._meta.fields: 
      ele.attrib[field.attname]=str(getattr(self,field.attname)) 
     return ele 
    models.Model.to_element = to_element 

Esto añade un método para modelar lo que crea una instancia del elemento que contiene los campos de la modelo que se preocupa, sin la costra Django.

Entonces, para construir el documento XML, simplemente hacer esto:

dealer = Dealer.objects.get(id=dealer_id) 
makes = DealerMake.objects.filter(dealer=dealer) 

root = dealer.to_element() 
for make in makes: 
    root.append(make.to_element()) 

xml = ET.tostring(root) 
print xml 

Con este enfoque se puede obtener un documento XML con un formato agradable con todos los campos de modelo de Django como atributos, y construir una jerarquía profunda de nivel n . Cada nodo xml tendrá el mismo nombre que la clase de modelo.

Cuestiones relacionadas