2010-09-30 25 views
11

Potrzebuję zapisać dane modelu (tylko CharField) do pliku XML, aby zawierał dane dla pliku flash. Jestem na to nowy i proces ten jest dla mnie trochę niejasny, ponieważ robię to w django. Tworzę plik xml, a następnie zapisuję dane tekstowe do pliku (tak jak w przypadku modułu csv, ale do xml). Bardzo uproszczony plik xml powinien prowadzić do pliku Flash czytać, tj:Generowanie pliku XML z danych modelu

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

1. Używam serializatora do zapisu danych XML z modelu

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

2. Następnie utworzyć plik, używając core.files:

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

3. dane zapisu pliku i zamknij

myfile.write(data) 

myfile.close() 

To działa do tej pory, chociaż wyjściowe xml zawiera pola dla obiektu "django-objects" itp. I będę musiał zobaczyć, czy mogę to zinterpretować w ActionScripcie z łatwością dla pliku flash. Wolałbym definiować nazwy pól xml ręcznie, jak w module csv. Ponieważ jestem nowy w Django i Pythonie, zastanawiam się, czy jest łatwiejszy i prostszy sposób na zrobienie tego?

Uwaga: W serializatora używam filtru na modelu obiektów, ponieważ używając get dla instancji modelu zwraca błąd object not iterable. W rzeczywistości filtruję go dwukrotnie, aby uzyskać pojedyncze wystąpienie, wydaje się, że musi istnieć lepszy sposób.

+0

Nie mam jasności co do pożądanego formatu XML. Czy element 'textField' jest równy jednemu wierszowi w bazie danych, z których każdy ma pojedyncze pole? Jeśli tak, to jaki jest numer "identyfikatora"? Jeśli nie, w jaki sposób rozróżniasz wiersze? –

+0

Czy uważasz, że JSON jest formatem serializacji? O wiele łatwiej jest tworzyć i konsumować. –

+0

Tak, textField byłby pojedynczym wpisem charField w DB (każde pole wejściowe db do wypełnienia pola tekstowego w pliku flash). Niestety, id był nieco mylący, chodzi o to, że istnieje wiele pól tekstowych w pliku flash, więc id odpowiadają różnym charFields w modelu. Powinny być różne modele charFields. Teraz zajmuję się JSON-em, zwykle używam xml z AS3, wydaje mi się, że JSON wymaga importowania bibliotek AS3, a dla tej aplikacji niestety nie jest to opcja. – HdN8

Odpowiedz

25

Masz dwa możliwe rozwiązania tutaj:

1.

można rozszerzyć serializatora baza Django xml (django.core.serializers.xml_serializer.Serializer) i zmodyfikować go tak zwróci dane w swojej strukturze. Możesz wtedy uruchomić ex.

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

i wyświetli dane w twojej strukturze.

2.

Napisz prostą funkcję, która będzie świadczyć szablon ze swojej struktury danych i powrócić danych XML w formacie:

kodu Pythona

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 

Szablon xml_template.xml

<?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, opcja 2 wygląda optymalne rozwiązanie, więc mogę zdefiniować strukturę xml przy użyciu render_to_string i predefiniowany szablon (który może być nawet tylko plik tekstowy, jak przypuszczam). Następnie używam metody file.write() z "xml" jako treścią ... ok świetnie, postaram się zaimplementować tę opcję, dzięki! – HdN8

+0

Tak, szablon jest plikiem tekstowym. –

+0

Brilliant. Działa bez zamieszania. +1 – Glycerine

1

Aby uzyskać bardziej ogólne podejście do rozwiązania tego problemu, można uniknąć szablonów za pomocą prostego kliknięcia kciukiem w modelach i serializować dowolny głęboki wykres obiektów do XML za pomocą ElementTree.

Oto jak rozwiązać go:

Monkey modele patch/kaczka dziurkowania w modelu.py jak:

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 

Dodaje metodę do modelu, który tworzy instancję elementu zawierającego pola z modelu, które dbają o bez cruft Django.

Następnie, aby skonstruować dokument XML, po prostu to zrobić:

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 

Dzięki takiemu podejściu można uzyskać ładnie sformatowany dokument xml z wszystkich pól modelu django jako atrybuty i skonstruować n poziomie głębokie hierarchii . Każdy węzeł xml zostanie nazwany tak samo jak klasa modelu.