Django: Wo Timestamp-Format für HTML-Seite modifizieren?

Django, Flask, Bottle, WSGI, CGI…
Antworten
Piet Lotus
User
Beiträge: 80
Registriert: Dienstag 14. November 2006, 10:40

Hallo zusammen,
ich experimentiere gerade mit GenericViews. Ich möchte gerne ein "Warnung" beim Modifizieren eines Datenbank-Objektes ausgeben, wenn zwischenzeitlich das Datenbank-Objekt durch einen anderen User geändert worden ist. Es geht also um einen konkurrierenden Zugriff. Zur Verdeutlichung ein Beispiel aus einem Wiki. Nutzer "A" möchte eine Wikiseite "Seite XYZ" korrigieren, ruft sie auf und führt seine Änderungen durch. Ein anderer Nutzer "B" hat ebenfalls einen Fehler auf der Wikiseite "Seite XYZ" gefunden und korrigiert parallel zum Nutzer "A" die Seite, speichert aber vor Nutzer "A" seine Änderungen. Wenn jetzt Nutzer "A" speichert, dann werden die Änderungen von Nutzer "B" überschrieben, da Nutzer "A" auf einem alten Stand der Wikiseite gearbeitet hat. Dem Nutzer "A" soll jetzt eine Meldung ausgegeben werden, dass sein Stand der Seite veraltet ist. (Das nur zum Hintergrund, hat wahrscheinlich mit meinem eigentlichen Problem nicht unbedingt was zu tun.)
Machen kann man dass, indem man einen Timestamp "letzte_aenderung" an die Datenbank-Objekte hinzufügt und diesen Zeitstempel, z.B. über ein "Hidden-Field" auf der Bearbeitungsseite mitgibt. Dieses "Zeitstempel-Hidden-Field" wird dann vorm eigentlichen Speichern nochmal durch einen aktuelleren Datenbankzugriff auf das zu modifizierenden Objekt mit dem dort aktuell gespeicherten Zeitstempel verglichen. Sind die beiden Zeitstempel gleich, ist alles gut - sind die beiden Zeitstempel unterschiedlich, wurde das Objekt in der Zwischenzeit von jemanden anderen geändert und eine Warnung müsste ausgegeben werden. Das habe ich also vor...
Ich komme jetzt nicht weiter, in der HTML-Seite wird das Hidden-Field beispielhaft folgendermaßen dargestellt:

Code: Alles auswählen

<input id="id_bearbeitungszeitpunkt" type="hidden" value="24. Mai 2012 00:08:00" name="bearbeitungszeitpunkt">
das Timestamp-Feld enthält "24. Mai 2012" und führt beim Abschicken der Form zu einem Fehler

Code: Alles auswählen

Fehler: <ul class="errorlist"><li>bearbeitungszeitpunkt<ul class="errorlist"><li>Bitte ein gültiges Datum und Uhrzeit eingeben.</li></ul></li></ul>
Wenn ich über Firebug, den Wert auf "24.05.2012 ..." ändere, dann geht's weiter. Wo kann ich die Einstellung für den Timestamp vornehmen, so das gleich im Hidden-Field der Wert "TT.MM.YYYY ..." auftaucht und der Monat nicht mehr ausgeschrieben wird? Irgendwie finde ich nicht die richtige Schraube zum Drehen... :(
Viele Grüße und frohe Pfingsten
Piet
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Zeig mal deine Form und dein view. Das einfachste wäre IMHO ein DateTimeField mit einem datetime zu füttern und im view solltest du dann wieder ein datetime bekommen.

(Eigentlich sollte ich sowas mal in PyLucid implementieren...)

btw. ein anderer Ansatz wäre es, wenn du dem Anwender vor dem speichen bzw. beim start des editierens informierst, das gerade jemand anderes das selbe vor hat. So macht es glaube ich MoinMoin.
Ist allerdings aufwendiger zu implementieren, weil du an einer separaten Stelle speichern müsstest, wer gerade was ändert. Außerdem mußt du das abbrechen vom Editieren berücksichtigen.

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:

jens hat geschrieben:(Eigentlich sollte ich sowas mal in PyLucid implementieren...)
Gesagt getan. Allerdings erstmal nur im django1.4 branch und dem Blog Model.

@Piet Lotus: Vielleicht hilft die meine Änderungen dafür: https://github.com/jedie/PyLucid/commit ... dee378e8eb

Ich hab gleich noch eine Möglichkeit eingebaut, das der User dennoch speichern kann, also den neueren Inhalt mit seinen Daten überschreiben kann. Das ganze funktioniert mit einem kleinen Trick:

Zusätzlich zum versteckten Änderungsdatum in der Form, packe ich gleich noch eine versteckte CheckBox dabei.

Wenn nun also die Situation Eintritt, das im Hintergrund schon einen neuere Version gespeichert wurde *¹, dann erhält man die Form zurück und die CheckBox wird eingeblendet. Die "Fehlermeldung" ist ein form_error von dieser CheckBox, mit dem Hinweis das man diese CheckBox Aktivieren muß, damit beim nochmaligen Speichern der neuere Inhalt überschrieben wird. Würde man diese "überschreiben" Funktion raus nehmen, kann der User nur noch "abbrechen". Denkbar wäre natürlich auch kompliziertere Lösungen dafür *²

*¹ Es muß natürlich nicht zwingend ein zweiter User beteiligt sein: Der selbe User kann die Editier-Form in zwei Tabs/Browserfenster öffnen.

*² z.B. könnte man, wenn django-revision genutzt wird, darin einen neuen Eintrag machen, aber ansonsten nicht speichern. Die Komplizierte Lösung wäre ein diff in irgendeiner Variante, z.B. bekommt der User die Form wieder zurück, inkl. einem Diff vom Text. Kommt natürlich alles darauf an, für welche Daten ist das überhaupt ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Piet Lotus
User
Beiträge: 80
Registriert: Dienstag 14. November 2006, 10:40

Hallo Jens,
danke für deine Antwort, sie hat mich auf die richtige Spur gebracht. Der Hinweis hier doch mal die Form und die View zu zeigen brachten mich dazu mein Problem für das Forum aufzubereiten - und da merkte ich dass ich aus meinen Experimenten noch eine falsche Form verwendet habe. Danke für die Hilfe und sorry für den "Sturm im Wasserglas". Jetzt bekomme ich keine Zeitstempelfehler mehr, dafür hänge ich woanders - das Problem poste ich aber wenn ich noch mal einige Nächte über das Problem geschlafen habe - damit so ein Fehlalarm nicht noch mal passiert. Ich sollte nicht mehr bis in die Puppen programmieren, dann passieren solche dummen Fehler hoffentlich nicht mehr... :wink:
Vielen Dank
Piet
Antworten