sortierte Felder im Django-ORM

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

Donnerstag 31. Mai 2007, 10:48

EDIT (jens): Abgetrennt von http://www.python-forum.de/post-69265.html#69265
Leonidas hat geschrieben:Was ich gebraucht hätte, waren sortierte Felder im Django-ORM, was ich dann durch ein zusäzliches ``position``-Feld und einiges an Meta-Magie gelöst habe.
Ich weiß jetzt nicht genau, was du machen wolltest, aber funktioniert das nicht mit .order_by(): http://www.djangoproject.com/documentat ... -by-fields
Leonidas hat geschrieben:Der Mutually-Referential-Bug. Der ist inzwischen zwar geöst, aber das hat auch schon ziemlich lange gedauert.
Ja, das ist das dumme an django, das Änderungen seine Zeit brauchen. Auf der anderen Seite ist somit der trunk und die API recht stabil...
Leonidas hat geschrieben:das i18n-System ist fest an ``gettext`` verdrahtet.
Mit i18n hab ich mich noch nicht so viel beschäftigt.
Zuletzt geändert von jens am Donnerstag 31. Mai 2007, 11:18, insgesamt 1-mal geändert.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 31. Mai 2007, 11:01

jens hat geschrieben:
Leonidas hat geschrieben:Was ich gebraucht hätte, waren sortierte Felder im Django-ORM, was ich dann durch ein zusäzliches ``position``-Feld und einiges an Meta-Magie gelöst habe.
Ich weiß jetzt nicht genau, was du machen wolltest, aber funktioniert das nicht mit .order_by(): http://www.djangoproject.com/documentat ... -by-fields
Schau es dir mal an: #245. Damit erstelle ich durch ein Mix-In ein zusätzliches Feld im Model (und einen Manager, der an sich eigentlich unnütz ist), einige Funktionen um damit zu arbeiten und ich überschreibe einige Methoden, damit die Daten korrekt gespeichert und gelöscht werden können.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 31. Mai 2007, 11:25

(Hab das Thema mal geteilt...)

Also wenn ich dein Sourcecode richtig verstehe, willst du im Grunde eine sortierte Liste haben, ohne explizit ein "Positions"-Feld in deinem Model einzufügen, ja?
Wie kann man die Reihenfolge mit deinem Mixin im nachhinein ändern? einfach .position eine neue Zahl zuortnen?

Warum nicht explizit im Model sowas einfügen? Ich habe das so bei PyLucid gemacht. Jede CMS-Seite hat eine Gewichtung von -10 bin +10. Die Seiten auf einer Ebene werden nach dieser Zahl sortiert.

Normalerweise bekommen alle Modelle einen ID-Primary-Key... Man könnte eigentlich .order_by("id") machen. (Wobei man dann natürlich die Reihenfolge nicht mehr im nachhinein ändern kann.)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 31. Mai 2007, 11:41

jens hat geschrieben:Also wenn ich dein Sourcecode richtig verstehe, willst du im Grunde eine sortierte Liste haben, ohne explizit ein "Positions"-Feld in deinem Model einzufügen, ja?
Richtig.
jens hat geschrieben:Wie kann man die Reihenfolge mit deinem Mixin im nachhinein ändern? einfach .position eine neue Zahl zuortnen?
``move_up()``, ``move_down()``. ``position`` direkt zu verändern ist eine unglaublisch schlechte Idee, weil jede Position nur einmal vorkommen draf. Dadurch entstehen Lücken und doppelte Positionen und das zu reparieren ist danach quasi unmöglich. N aich müsste ich wohl nich ein Property machen, aber soweit ich weiß, werden Properties nicht vererbt. Kann das jemand bestätigen/widerlegen?
jens hat geschrieben:Warum nicht explizit im Model sowas einfügen?
Weil ich dann, um Sortierfähigkeit nachzurüsten an zig Stellen Felder und Werte und Manager reinsetzen müsste. Und so muss ich einfach nur das Mix-In reinladen - fertig. Jetzt kann ich dreißig Models machen die alle eine Sortierung haben, indem ich dreißig mal das Mix-In reinlade. Und nur das. Ich muss keine weiteren Felder definieren, die ich dann beim 28 Model vergessen könnte. Das Mix-In kümmert sich darum, dass diese Felder exisiteren.
jens hat geschrieben:Ich habe das so bei PyLucid gemacht. Jede CMS-Seite hat eine Gewichtung von -10 bin +10. Die Seiten auf einer Ebene werden nach dieser Zahl sortiert.
Mit so einer Gewichtung kannst du nur 21 Positionen genau ausgeben. Stell dir vor, du hast vierzig seiten, die alle eine bestimmte Reihenfolge erfordern. Was dann?
jens hat geschrieben:Normalerweise bekommen alle Modelle einen ID-Primary-Key... Man könnte eigentlich .order_by("id") machen. (Wobei man dann natürlich die Reihenfolge nicht mehr im nachhinein ändern kann.)
Genau. Sinn? Ich könnte die Objekte auch nach Namen sortieren, aber das würde doch ebensowenig das sein, was ich eigentlich erreichen wollte.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Donnerstag 31. Mai 2007, 11:44

jens hat geschrieben: Warum nicht explizit im Model sowas einfügen? Ich habe das so bei PyLucid gemacht. Jede CMS-Seite hat eine Gewichtung von -10 bin +10. Die Seiten auf einer Ebene werden nach dieser Zahl sortiert.
Ich habe die Sortierung auch direkt im Model. Nicht versteckt. Nichts verbogen. Es läuft gut. Und spätestens bei Nested Sets fällt mir kein "vernünftiges" verstecken mehr ein.

Warum nur von -10 bis +10? Ist das nicht ein wenig eingeschränkt? Ich starte genau bei 0 und es geht bis 2**32-1 ( natürlich noch höher bei bigint )
Aber gerade bei einem CMS würde ich zu Nested Sets raten. Besser, schneller und einfacher ist es nicht mehr möglich Baum und Sortierbare Liste zu vereinen. Man kann komplette Subbäume mit 1nem qry aus der DB holen.

Hier noch eine sehr einfache Erklärung zu den Nested Sets; http://www.klempert.de/nested_sets/artikel/

lgherby
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 31. Mai 2007, 11:53

thelittlebug hat geschrieben:Warum nur von -10 bis +10?
Das ist keine echte Limitierung im Model (Es ist ein models.IntegerField). Ich wollte dem User es nur einfach machen. Die einfachste Variante war für mich, die Position per HTML-Drop-Down Liste vom User auswählen zu lassen. Diese Liste sollte nicht super lang werden.

Denkbar wäre natürlich auch, das der User die Zahl einfach eintippt. Dann ist nur die Limitierungen des DB-Feldes ausschlaggebend.

Bisher hatte ich auch nicht soviele CMS Seiten auf einer Ebene. Außerdem habe ich auch nicht das bestreben bisher gespürt haarklein zu bestimmen in welcher Reihenfolge die Links im Menü vorkommen sollen. Wobei natürlich für die erste Ebene das schon wichtig ist...

Die CMS Seiten sind im Grunde als "Nested Sets" hinterlegt. Das hat aber IMHO nichts mit der Sortierung auf einer Ebene zu tun.
Btw. ich hab das auch noch ein Problem mit django in dieser Richtung: http://www.python-forum.de/post-68607.html#68607

EDIT:
thelittlebug hat geschrieben:Hier noch eine sehr einfache Erklärung zu den Nested Sets; http://www.klempert.de/nested_sets/artikel/
Danke für den Link!
Demnach nutzte ich doch keine "Nested Sets" sondern das "Parent-Modell": Die Kinder eines Knotens enthalten im Feld parent die id ihres Vorfahren

Hm... Muß ich mir mal in Ruhe reinziehen... btw. gibt es beispiel Implementierungen in Python?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:09

thelittlebug hat geschrieben:Ich habe die Sortierung auch direkt im Model. Nicht versteckt. Nichts verbogen. Es läuft gut.
Bei mir ist auch nichts versteckt und verborgen - es ist einfach automatisiert. Don't repeat yourself.

Ich habe grad noch ein wenig rumgeschsut: falls ich wieder dazu komme, werde ich das ganze noch etwas modifizieren:
  • Der Sorting Manager fliegt raus. Sinnlos und unbrauchbar. Man muss dann selbst filtern()
  • Werde in der 'Meta'-Klasse in das Feld ``ordering`` vorne ``position`` einfügen. Dadurch sind die Objekte automatisch richtig sortiert, auch wenn man nur eine Unterauswahl macht. Gefällt mir.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:11

Beispiel in Python hab ich bis jetzt noch keines gefunden. In PHP gibt es etliche. Wobei die Programmiersprache recht egal sein sollte da das ganze Verhalten eh zu 90% aus SQL besteht.

Ich mach mir da eher Sorgen in Verbindung mit ORM's und DBA Layern, Nested Sets werden sich nicht so leicht Datenbankübergreifend realisieren lassen. Mit PostgreSQL kommt man sicher leichter durch als mit MySQL. Eventuell müsste man da den kleinsten gemeinsamen Befehlssatz finden und hoffen das es dann auf jeder DB läuft (wenn auch nicht auf jeder ideal)

lgherby
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:19

jens hat geschrieben:Die einfachste Variante war für mich, die Position per HTML-Drop-Down Liste vom User auswählen zu lassen. Diese Liste sollte nicht super lang werden.
Hier hätte ich 2 Vorschläge:
1. Der User bekommt in der DropDown Liste die Seitennamen die in der aktuellen Ebene vorhanden sind. Wählt er eine Seite aus wird die aktuelle dannach gereiht ( ist ne definitionssache, aber dannach gefällt mir gut ). Natürlich braucht die Dropdown Liste auch einen "Startpunkt", wird eine Seite nach den Startpunkt gereiht ist sie klarerweise 1ste ;)
Das verhalten muss nicht unbedingt mit einer Dropdownliste realisiert werden. Denkbar wären auch Links:
Root
Home
AGB
Impressum
^^ Je nachdem worauf er klickt wandert die aktuelle gleich dahinter.
2. Verwenden von JS, Flash, Java, was weiß ich was sonst noch gibt :)
Verwenden von JS vor allem in Verbindung mit EXTJS http://www.extjs.com gefällt mir sehr gut. Ich habe mir z.b. mit Pylons eine Verwaltung für eine Baumstruktur gebaut, natürlich durch EXTJS mit drag&drop und ähnlichen Spielereien. Läuft sehr gut.

edit: lgherby :D
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:32

jens hat geschrieben:Das ist keine echte Limitierung im Model (Es ist ein models.IntegerField). Ich wollte dem User es nur einfach machen. Die einfachste Variante war für mich, die Position per HTML-Drop-Down Liste vom User auswählen zu lassen. Diese Liste sollte nicht super lang werden.
Irgend wie scheint mir das alles andere als Elegant zu sein ;) Wie sortiere ich damit mehr als 10 Elemente? 0, 1, ∞ ;)
Da halte ich die Lösung von Leonidas für um einiges eleganter. Auch wenn ich diese Funktionalität gerne im ORM selbst sehen würde.
jens hat geschrieben: Denkbar wäre natürlich auch, das der User die Zahl einfach eintippt. Dann ist nur die Limitierungen des DB-Feldes ausschlaggebend.
Das ist doch mühsam. Als Benutzer will ich ein Element an eine Position verschieben. Die ganzen anderen Elemente entsprechend zu updaten ist dann Sache der Software. Irgend wie erinnert mich das Konzept an meine Zeit mit Basic. Immer in 10ner Schritten nummerieren damit man später noch etwas einfügen kann. Hat es keinen Platz mehr gibt es entweder ein goto oder sämtliche folgenden Zeilen müssen erhöht werden ;)
jens hat geschrieben:Bisher hatte ich auch nicht soviele CMS Seiten auf einer Ebene. Außerdem habe ich auch nicht das bestreben bisher gespürt haarklein zu bestimmen in welcher Reihenfolge die Links im Menü vorkommen sollen. Wobei natürlich für die erste Ebene das schon wichtig ist...
Ich weis ja nicht, aber ich mag Software nicht die nur so etwa tut was ich will.
thelittlebug hat geschrieben: Ich habe die Sortierung auch direkt im Model. Nicht versteckt. Nichts verbogen. Es läuft gut. Und spätestens bei Nested Sets fällt mir kein "vernünftiges" verstecken mehr ein.
Hm ich fände es eine ziemlich tolle Sache wenn der ORM die Verwaltung der Nested Sets abnehmen würde. Sehe auch keinen Grund warum das Technisch nicht möglich sein sollte. Kann SQL Alchemy/Elixir das?

Ob Nested Sets wirklich nützlich sind hängt meiner Meinung nach stark vom Anwendungsfall ab. Ob es für die Seiten in einem einfachen CMS wirklich DER Weg ist weis ich nicht, ich denke aber eher nicht. Ich wüsste Spontan nicht wo bei den Seiten in einem einfachen CMS massiv Performance gewinne durch Nested Sets zu beobachten sind. Stell mir den Nutzen da eher bei der Benutzer/Rechte Verwaltung vor. Wobei .... wenn man Eigenschaften von Seiten vererbt könnten Nested Sets schon ganz toll sein ;)
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:47

veers hat geschrieben:Auch wenn ich diese Funktionalität gerne im ORM selbst sehen würde.
Ich habe sie so weit wie möglich ins ORM integriert. Als Nutzer, d.h. Model-Programmierer musst du nur noch vom Mix-In erben und los gehts.

Naja, auf dass die dritte Implementation besser wird :) Von der Bediehnung wird sie gleich sein, ich hoffe aber, dass ich es von der Implementation sauberer hinbekomme.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 31. Mai 2007, 12:54

jens hat geschrieben:EDIT:
thelittlebug hat geschrieben:Hier noch eine sehr einfache Erklärung zu den Nested Sets; http://www.klempert.de/nested_sets/artikel/
Danke für den Link!
Demnach nutzte ich doch keine "Nested Sets" sondern das "Parent-Modell": Die Kinder eines Knotens enthalten im Feld parent die id ihres Vorfahren
Hm. Schade, bei den Performance wird beim "Parent-Modell" die DB rekusiv abgefragt. So wie ich das verstehe, macht man also zig abfragen hintereinander. Ich verfolge da allerdings einen anderen Weg. Ich frage einmalig alle IDs mit parents ab und Analysiere dann die Daten. Mich würde mal interessieren, wie sich das dann im Vergleich mit den "Nested Sets" schlägt.

Klar ist, das "Parent-Modell" skaliert nicht so gut wie die "Nested Sets" Methode. Dafür wird diese aber beim einfügen von Daten immer langsamer und ist deutlich unübersichtlicher in der Programmierung.

Wäre natürlich echt super, wenn ein ORM das alles im Hintergrund abnehmen würde.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Donnerstag 31. Mai 2007, 13:30

Leonidas hat geschrieben:
veers hat geschrieben:Auch wenn ich diese Funktionalität gerne im ORM selbst sehen würde.
Ich habe sie so weit wie möglich ins ORM integriert. Als Nutzer, d.h. Model-Programmierer musst du nur noch vom Mix-In erben und los gehts.

Naja, auf dass die dritte Implementation besser wird :) Von der Bediehnung wird sie gleich sein, ich hoffe aber, dass ich es von der Implementation sauberer hinbekomme.
Das habe ich gesehen. Ich habe mehr gemeint dass ich das ganze lieber im Django ORM drin sehen würde als extern. Das ist klar nützlicher als ein USStateField oder ein PhoneNumberField.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 31. Mai 2007, 13:36

Zum Thema "Nested Sets" gibt es eine django Implementierung hier:
http://code.djangoproject.com/wiki/Modi ... eTraversal
bzw.
http://groups.google.com/group/django-u ... 8b858c2d33

Aber ich weiß nicht, ob der Code was taugt...

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

Dienstag 26. Juni 2007, 06:16

jens hat geschrieben:Klar ist, das "Parent-Modell" skaliert nicht so gut wie die "Nested Sets" Methode. Dafür wird diese aber beim einfügen von Daten immer langsamer und ist deutlich unübersichtlicher in der Programmierung.
Was mir da noch einfällt. Dadurch das der zentrale View in PyLucid gecahced wird, ist es eigentlich egal, das mit dem Parent-Modell nicht die schnellste Methode gewählt wurde.
Ich denke die Vorteile von Nested Sets würden erst bei sehr, sehr großen Seiten überhaupt zum tragen kommen.

Von daher bleibe ich doch lieber bei der sehr übersichtlichen und einfachen Lösung ;)

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