django models...

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 06:15

Kennt jemand einen Weg um zusätztliche django models zu benutzten ohne das diese in der "Haupt model datei" eingebunden ist, oder als seperate django app (settings.INSTALLED_APPS) eingebunden wurde?

Ich überlege gerade, wie PyLucid Plugins eigene models bekommen können, siehe: http://pylucid.org/phpBB2/viewtopic.php?t=227 (en)
Das ist dann interessant, wenn man aufwendigere Plugins realisieren möchte, wie ein kleines Blog, Forum oder Kommentar funktion...

Mir fällt spontan nur ein, das jeweilige Plugin auch in settings.INSTALLED_APPS aufzuführen, obwohl es keine eigenständige Applikation in dem Sinne ist. Das funktioniert, habe es schon einmal getestet.
Mit INSTALLED_APPS umgeht man aber in gewisser weise den PyLucid plugin Administrator. Wenn man also damit ein Plugin installiert / deinstalliert, hat es keine Auswirkung auf die zusätzlichen Tabellen. Ganz so schlimm wäre das aber auch nicht...

Ich denke es gibt zwei Knackpunkte, wenn man nicht INSTALLED_APPS nutzt: Das erzeugen der Tabellen mit syncdb und das initialisieren der models Klassen.

Weiß jemand wie genau models initialisiert werden? Ist es aufwendig das selber zu machen?

Ich könnte mir vorstellen, das es via MonkeyPatch gehen würde, aber das ist wohl nicht gerade die beste Art und Weise.

Evtl. könnte auch das existierende models.py die plugin models selber importieren und fertig.

EDIT: Hm. Denke ich da eigentlich zu kompliziert? Könnte man einfach irgendwo eine models klasse erstellen und nutzten, wenn die passende Tabelle existiert?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Freitag 30. Mai 2008, 07:16

Ich bin mir jetzt nicht sicher, obs dafür gedacht ist aber django.core.sql.sql_model_create sieht danach aus, was du suchst.

Oder du nutzt ein Model das den Tabellennamen definiert:

Code: Alles auswählen

class MyModel
    # columns...

    class Meta:
        db_table = 'my_db_table'
Dann könnte der Pluginautor für ne *.sql Datei sorgen in der seine DB-Struktur erstellt wird (weiß nicht, aber sql_model_create siehe oben sieht danach aus, als obs' der automatische Weg währe). Solltest du plain SQL nutzen, brauchst dann nur noch django.core.sql.custom_sql_for_model anzuschauen.


Hoffe ich konnte helfen.
MfG EnTeQuAk
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 30. Mai 2008, 12:53

EnTeQuAk hat geschrieben:Dann könnte der Pluginautor für ne *.sql Datei sorgen in der seine DB-Struktur erstellt wird (weiß nicht, aber sql_model_create siehe oben sieht danach aus, als obs' der automatische Weg währe).
Ja, für jede unterstützte SQL-Datenbank eine eigene Datei, da bin ich mal gespannt wie viele das so machen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 14:45

Ne, .sql Dateien mitschleppen kommt nicht in frage ;)

Aber ich bin mir sicher, das man den CREATE TABLE Statement durch django erhalten kann. Die Frage ist nur, ob ein seperat definiertes Model funktionieren würde und wieviel Aufwand es ist, damit es funktioniert.

Das wäre ich später mal testen...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 16:55

Ha. Es funktioniert. Wenn die Tabellen da sind, kann die model klasse irgendwo sein und man kann damit arbeiten. Jetzt ist die Frage, bekomme ich wirklich den CREATE TABLE statement herraus?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Freitag 30. Mai 2008, 17:11

importiere sie doch einfach über ne Funktion in deiner models.py
[also in den Namespaces des moduls natürlich. __import__ kann sowas. vllt gehts auch einfach so..ka grad.]

Ist ein bischen dunkle Magie...aber nunja, Plugin halt :D
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 17:33

audax hat geschrieben:importiere sie doch einfach über ne Funktion in deiner models.py
Ja, das wäre evtl. möglich. Ein andere möglichkeit wäre evtl. INSTALLED_APPS zur Laufzeit zu erweitern?

EDIT: Den CREATE TABLE code bekommt man übrigends mit django.core.management.sql.sql_model_create

Das doofe sind die Referenzen...

EDIT2: Ich glaube es ist viel einfacher als ich dachte! Wenn ein admin ein plugin installiert, wird einfach alle zugehörige Module importiert und ein "syncdb" erzeugt dann die Tabellen, weil die models ja zur PyLucid-App gehören... Anscheinend! Muß es noch mal richtig Testen...

EDIT3: Es funktioniert. PyLucid braucht also nur die Plugin models zu importieren und danach kann mit einem syncdb die Tabellen erzeugt werden.
Weiß jetzt nur nich was sinn macht bei den Meta angaben:

Code: Alles auswählen

    class Meta:
        db_table = 'PyLucid_test4'
        app_label = 'PyLucid'

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 20:50

Also ich hab jetzt was... Um and die CREATE TABLE statements zu kommen, kann man sowas machen:

Code: Alles auswählen

from django.core.management.color import no_style
from django.core.management import sql
style = no_style()

def get_create_table(models):
    statements = []
    for model in models:
        statements += sql.sql_model_create(model, style)[0]
        statements += sql.sql_indexes_for_model(model, style)
        statements += sql.custom_sql_for_model(model)
    return statements
Wobei models eine liste der model Klassen sein muß, aber das ist kein Problem.


Nun sollten ja auch die Tabellen verschwinden, wenn man ein Plugin wieder deinstalliert... Das ist ehr das Problem :( Es gibt leider keine gegenstücke für die obrigen Funktionen.

Das einzige was ich gefunden hab ist das:

Code: Alles auswählen

from django.core.management import sql
from django.db.models import get_app
from django.core.management.color import no_style

style = no_style()
app = get_app("PyLucid")
statements = sql.sql_delete(app, style)
Damit bekommt man allerdings alle DROP Statements für alle Modelle einer App :(

Bleibt die Idee INSTALLED_APPS zur Laufzeit zu verändern, um an die Daten zu kommen... Aber ob das eine gute Idee ist?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 30. Mai 2008, 22:12

Eine neue Idee.

Also man kann INSTALLED_APPS zur Laufzeit zu verändern. Allerdings muß man die Models der App per Hand registrieren. Es funktioniert aber im Test: http://pylucid.net:8080/pylucid/changeset/1607

Besser ist es aber wohl die INSTALLED_APPS unangetastet zu lassen. Die Überlegung ist, ob man nicht duaerhaft ein "Dummy" App einbindet und dann nur mit django.db.models.loading.register_models models temporär hinzufügt und mit del(django.db.models.loading.cache.app_models["PyLucidPlugins"]) sie wieder löscht.

Ich frage mich allerdings ob das in einer fastCGI Umgebung kein Ärger gibt? Auf der anderen Seite geht's ja eigentlich nur um das Deinstallieren von einem Plugin...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 31. Mai 2008, 23:41

So, ich hab nun anscheinend alle Klippen umschifft. Mit http://pylucid.net:8080/pylucid/changeset/1612 scheint erstmal alles prima zu laufen.

PyLucid plugins können nun sehr einfach eigene django ORM models haben. Die nötigen Tabellen werden automatisch erzeugt, wenn man das Plugin per plugin manager installiert und ein DROP TABLE gibt es auch, wenn man das plugin wieder kickt.

Nutzten kann man die Models wie ganz normale django ORM modelle. Man kann auch Relationen zu existierenden django/PyLucid tabellen nutzten.

Das einzige was nicht so richtig geht, ist die Tabellen im django admin panel zu bearbeiten.

Doku, wie das alles geht ist zumindest angefangen: http://www.pylucid.org/_goto/163/plugin-models/

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten