django: dynamische urlpatterns

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

In der nächsten PyLucid Version wollte ich mal ran und die urls ändern. Dabei Frage ich mich gerade, wie dynamisch man diese aufbauen kann.

Kann man die urlpatterns anhand von Daten aus der Datenbank aufbauen? Hat das schon jemand mal versucht?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Kann man die urlpatterns anhand von Daten aus der Datenbank aufbauen?
Natürlich. Man leitet einfach alle URLs an eine Funktion die dann die Patterns aus der DB holt und weiter dispatcht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

... wobei du beim reversing probleme bekommen wirst...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

apollo13 hat geschrieben:... wobei du beim reversing probleme bekommen wirst...
Genau das habe ich auch schon gehört. Ich kann aber nicht wirklich einschätzen, welche Probleme ich damit bekommen werde...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

jens, willst du die URLs von einem Benutzer während der Laufzeit ändern lassen können? Falls nein, dann sehe ich nicht, wieso eine Datenbank-gestützte Lösung besser wäre als `urls.py` zu verändern. URLs zur Laufzeit ändern scheint mir komisch, widersprechen sie doch dem "ewigen" Charakter einer URLs: immer und für alle Zeit auf eine Ressource zu verweisen.

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Genau darum geht es. Der Benutzer soll sagen können das Plugin XY soll nun unter der URL XY erreichbar sein.

Das Problem ist immer das selbe: django ist darauf ausgelegt, alles per settings.py/url.py zu konfigurieren. Ich hingegen möchte in PyLucid alles per Web-Oberfläche in einfacherer Form editierbar machen.

Das unter einen Hut zu bringen ist nicht einfach ;)

Das Problem wird sein: Wenn der User urls per Datenbank ändert, werden laufende fastCGI Prozesse davon nichts mit bekommen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Die flatpages konfigurieren ihre URLs doch auch quasi dynamisch. Warum machst du das nicht genau so? Du hast einen Präfix wie z.B. "/plugin/" und ab da verwaltest du die URLs selbst.

Wenn du's nicht komplett dynamisch machen willst, kannst du zur Laufzeit ja eigene RegexURLResolver erzeugen und einhängen, allerdings modifiziert das natürlich nur den Prozess, in dem das gerade abläuft und nicht alle. Hier rächt sich, dass Python nicht multithreading-fähig ist und man daher immer mehrere Prozesse braucht. Eine Java-App-Server könnte es... :)

Django baut sich im Request-Handler einen RegexURLResolver basierend auf dem request.urlconf-Attribut (oder der `urls.py` aus den Settings). Hier könntest du eingreifen.

Wichtig ist nur, dass alle Prozess erkennen, wenn sich etwas geändert hat und sie ihre Caches wegschmeißen.

Neue Plugins haben ja so oder so Code. Daher fände ich es auch nicht schlimm, wenn diese ihre Konfiguration aus einer urls.py-Datei lesen. Das funktioniert automatisch, wenn die Datei im Python-Suchpfad zu finden ist. Aber auch das ist klar, denn man muss ja den restlichen Code auch lesen können.

Dennoch, meines Wissens gibt es (im Gegensatz zu Java) keinen definitiven Lifecycle fürWebanwendungen oder Plugins oder sonstwas und ich hätte Angst, das selbst wenn man das Zeug laden kann, das Entladen schwer werden könnte.

Klingt aber nach einem spannenden Problem und ich fände es klasse, so ein Plugin-System zu haben.

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das bisherige PyLucid Plugin System arbeitet ja auch mit einem Prefix: "_command"... Aber man bekommt halt unschöne URLs.

Die aktuelle urls.py sieht so aus:
http://trac.pylucid.net/browser/trunk/p ... y?rev=1723

Bsp. das Blog Plugin: Auf PyLucid org ist es hier erreichbar: http://pylucid.org/developer-blog/
Diese URL kann man beliebig ändern. Aber, wenn ein bestimmte Method des Plugin angesprungen wird, dann kommt das Prefix zum Einsatz, z.B.:
  • ...pylucid.org/_command/166/blog/detail/9/
    ...pylucid.org/_command/166/blog/tag/django/
    ...pylucid.org/_command/166/blog/feed/entries.atom
(Wobei 166 die ID der Seite ist. Da könnte man auch besser ein slug benutzen)

Schöner wären aber solche URLs:
  • ...pylucid.org/developer-blog/detail/9/
    ...pylucid.org/developer-blog/tag/django/
    ...pylucid.org/developer-blog/feed/entries.atom
Das geht aber z.Z. einfach nicht. Mein Problem: Ich kann in der urls.py nicht unterscheiden ob es eine normale CMS Seite ist, oder ein Plugin.

Eine Lösung wäre es quasi ein eigenen url-Resolver zu bauen. Also man packt in die Datenbank die URLs und die Info, welche Seite oder Plugin ist es.
In der urls.py gibt es nur eine sehr Allgemeine Regex, die quasi auf fast alles trifft. Im view wird dann die url in der Datenbank nachgesehen und der eigentliche view wird gestartet...

Im Grunde mache ich das jetzt schon, bei den normalen CMS-Seiten urls, die urls-Regex sieht dazu so aus: (r'([\w/-]*)', 'PyLucid.index.index'),

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also wenn ich das jetzt richtig sehen, würde es im Grunde darauf hinauslaufen, das in z.B. fastCGI Umgebung Änderungen an den urlpatterns erst dann wirksam werden, wenn der aktuelle fastCGI Prozess neu gestartet hat.

Die Frage ist also, kann man aus der django app einen "reload" auslösen???
Der WSGI Standard hat da nicht wirklich was für vorgesehen, oder?

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