Django: Einfache Backups von belieben Models machen?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
killercup
User
Beiträge: 16
Registriert: Mittwoch 19. Dezember 2007, 15:58

Hallo,

ich baue gerade an einer kleinen Django-App, welche von einem beliebigen Model ein XML-Backup erstellen können soll. Das ganze spielt sich in einem einzigen View ab, der über /backup/<app>/<model>/ erreicht werden soll. Mein Problem ist jetzt nur, dass ich das ganze flexibel gestalten muss, weil es ja jedes beliebige Model sein kann.

Anfangsschwierigkeit für mich als Python-Lernenden ist erstmal: Wie kann ich von einer Variable importieren? Mag seltsam klingen, aber ich muss ja erstmal das Model anhand des URL-Parameters importieren. Sachen wie

Code: Alles auswählen

import '%s.models.%s' % (app, model) as MyModel
funktionieren ja leider nicht… Einzige Möglichkeit wäre natürlich alles zu importieren, aber dann hätte ich wieder keinen "Namen", um mein Model auszuführen (MyModel.objects.all() wäre da ja kein Problem). Ich hoffe, mir kann einer sagen, wie ich das ganz lösen kann…

Als nächstes muss ich natürlich noch eine Möglichkeit finden, alle Felder des Models mit Namen auszulesen… auch da habe ich keinen blassen Schimmer, wie das gehen soll… Ich hab mich in den Django Admin Dateien schon mal was umgesehen und die Funktion "get_model" gefunden, weiß aber noch nicht genau, was sie macht. Ich hoffe, auch hier kann mir jemand erklären, wie ich so etwas machen kann.

Mein Template soll am Ende also etwa so aussehen, wobei entries die Datensätze aus MyModel.objects.all() ist und fields die Felder des Models sind (und demnach entry.fields der Inhalt für das Feld):

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<{{app}}>
	{% for entry in entries %}
	<{{model}}>
		{% for field in entry.fields %}
		<{{field.name}}>{{entry.field}}</{{field.name}}>
		{% endfor %}
	</{{model}}>
	{% endfor %}
</{{app}}>
Vielen Dank für eure Hilfe! Ich hoffe, das lässt sich mit den richtigen Meta-Funktionen so machen!

Pascal[/code]
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Du kannst `get_model()` benutzen, um an eine beliebige Modell-Klasse zu kommen. Dort gibt es ein `_meta`-Attribut, um z.B. an die Liste der Felder, der Relationen usw. zu kommen. Zum Beispiel:

Code: Alles auswählen

from django.db.models import get_model

model = get_model('app', 'model')
print [f.name for f in model._meta.fields()]
Stefan
killercup
User
Beiträge: 16
Registriert: Mittwoch 19. Dezember 2007, 15:58

Wow, danke sma! Das war echt schnell! Das ist genau das, was ich gesucht hab. :) Kam bei dem Django-Admin-Code nicht so ganz rüber, was das genau ist.

Wie kann ich denn jetzt auf den Inhalt des Models zugreifen? Mit dem normalen "model.objects.all()" scheint es nicht zu gehen...
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Es gibt bereits in Snippet welches Django models nach Python Code Synchronisiert. Das könnte dir helfen.

http://www.djangosnippets.org/snippets/14/

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

killercup hat geschrieben:Mit dem normalen "model.objects.all()" scheint es nicht zu gehen...
Ich habe das eben probiert und bei mir geht das.

Code: Alles auswählen

model = get_model('app', 'whatever')
for m in model.objects.all():
  for f in model._meta.fields:
    print f.name, getattr(m, f.name)
Stefan
killercup
User
Beiträge: 16
Registriert: Mittwoch 19. Dezember 2007, 15:58

Nochmals vielen Dank Stefan! Mein Problem war leider nur ein dummes "s"...

Es funktioniert jetzt einwandfrei! Demnächst werde ich mir dann auch mal die gzip Funktion ansehen, um die XML-Daten auch komprimiert zum Download bereit zu stellen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Gibt es dafür nicht schon eine fertige Middleware?

Stefan
killercup
User
Beiträge: 16
Registriert: Mittwoch 19. Dezember 2007, 15:58

Ja, aber ich möchte dem User eine xml.gz-Datei entgegen werfen, für persönliche Backups oder später auch einfach für nen Cron-Job.

Die GZip Middleware komprimiert nur zur bessren Performance die Response-Objekte, außerdem die hab ich schon im Einsatz ;)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich denke eine gute Idee wäre es, db_dump.py so zu modifizieren das es nicht direkt mit file() Dateien schreibt, sondern mit file-like-Objekte arbeitet.
Dann könnte man direkt eine ZIP Datei bauen lassen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten