[Django] created_by in model automatisch befüllen Erklärung?

Django, Flask, Bottle, WSGI, CGI…
Antworten
blablabla
User
Beiträge: 6
Registriert: Freitag 7. Oktober 2011, 16:50

Hallo,

Ich bin neu hier und beschäftige mich mit Django nun möchte ich gerne in einem Model durch bearbeiten im Admin-Panel automatisch die Felder "erstellt_von" und updated_von" durch die User Tabelle befüllen.

Dies hab ich jetzt auch hinbekommen durch diese Seite https://code.djangoproject.com/wiki/Coo ... minAndUser
leider habe ich das Problem das ich einfach nicht verstehe wieso ich das so mache... und ich würde es gerne verstehen weil ich will es ja lernen und nicht nur abschreiben...

Was ich nicht verstehe ist genau dieser Punk:

Code: Alles auswählen

    def save_model(self, request, obj, form, change): 
        instance = form.save(commit=False)
        instance.user = request.user
        instance.save()
        form.save_m2m()
        return instance

    def save_formset(self, request, form, formset, change): 
        def set_user(instance):
            instance.user = request.user
            instance.save()

        if formset.model == Comment:
            instances = formset.save(commit=False)
            map(set_user, instances)
            formset.save_m2m()
            return instances
        else:
            return formset.save()
Ich hoffe ihr könnt mir helfen das zu verstehen
Danke

edit sorry hatte mich verschrieben created_by = erstell_von...
Zuletzt geändert von blablabla am Montag 10. Oktober 2011, 08:28, insgesamt 1-mal geändert.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Hä, suchst du nicht einfach nur die`auto_now_add`- und `auto_now`-Optionen von `DateTimeField`s?
blablabla
User
Beiträge: 6
Registriert: Freitag 7. Oktober 2011, 16:50

Hi,

nicht wirklich weil ich suche created_by (erstellt von) und und nicht created_at

wie gesagt ich habe es auch dadurch hinbekommen, allerdings verstehe ich den code leider nicht
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

In deiner Beschreibung steht aber "am" und nicht "von".

Warum updatest du nicht einfach von Hand die Felder in den Views?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Man kann es auch im Model.save() machen, wenn man eine Thread-local Lösung nutzt, z.B.:

Code: Alles auswählen

    def save(self, *args, **kwargs):
        current_user = ThreadLocal.get_current_user()

        if current_user and isinstance(current_user, User):
            if self.pk == None or kwargs.get("force_insert", False): # New model entry
                self.createby = current_user
            self.lastupdateby = current_user

        return super(UpdateInfoBaseModel, self).save(*args, **kwargs)
ThreadLocal.get_current_user() sieht so aus: https://github.com/jedie/django-tools/b ... adLocal.py

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

uäääää
blablabla
User
Beiträge: 6
Registriert: Freitag 7. Oktober 2011, 16:50

@jens

Danke für den Tipp, werd ich mir auf alle Fälle ansehen.

jedoch ändert das nichts an der Tatsache das ich oben stehenden Code irgendwie nicht ganz Raffe...


@per hand updaten
Der Sinn der Sache soll sein das ein User der sich im Adminpanel anmeldet und etwas ändert, in der Datenbank gespeichert wird damit man im Nachhinein weiß wer was wann gemacht hat.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dauerbaustelle hat geschrieben:uäääää
Was willst du uns damit sagen?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

@jens: Ich nehme an er will damit sagen, dass du nicht immer Threadlocals als Möglichkeit anbieten sollst, vor allem wenn Django selbst dafür ne API abietet.

@topic: Uhm, das Beispiel dort ist etwas broken ich habs mal angepasst: https://code.djangoproject.com/wiki/Coo ... minAndUser
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

apollo13 hat geschrieben:@jens: Ich nehme an er will damit sagen, dass du nicht immer Threadlocals als Möglichkeit anbieten sollst, vor allem wenn Django selbst dafür ne API abietet.
Die API bezieht sich aber nur auf den Admin Teil. Wenn man in eigenen views irgendwas ändert, wir der User nicht fest gehalten.

Mit einer Threadlocals Lösung im Model, werden alle Änderungen berücksichtigt, weil es halt tiefer ansetzt... Was ist so schlimm daran?

EDIT: Ach, bei der Lösung von https://code.djangoproject.com/wiki/Coo ... minAndUser muß man auch zweimal im Grunde das selbe machen. Hat man einen oder mehere views, hat man alles nochmal doppelt. Das ist nicht DRY...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

jens hat geschrieben:
apollo13 hat geschrieben:@jens: Ich nehme an er will damit sagen, dass du nicht immer Threadlocals als Möglichkeit anbieten sollst, vor allem wenn Django selbst dafür ne API abietet.
Die API bezieht sich aber nur auf den Admin Teil. Wenn man in eigenen views irgendwas ändert, wir der User nicht fest gehalten.
Er hat ja nur vom admin geredet…
Mit einer Threadlocals Lösung im Model, werden alle Änderungen berücksichtigt, weil es halt tiefer ansetzt... Was ist so schlimm daran?
Tendenziell fehleranfälliger und schwerer zu debuggen. Und was ist wenn man es aber nicht in allen Änderungen haben will? dann hat man ja wieder nen super Problem…
EDIT: Ach, bei der Lösung von https://code.djangoproject.com/wiki/Coo ... minAndUser muß man auch zweimal im Grunde das selbe machen. Hat man einen oder mehere views, hat man alles nochmal doppelt. Das ist nicht DRY...
Ach und die Kopplung von Request an deine Models ist jetzt sauberer Programmierstil? Du koppelst damit 2 Teile die eigentlich nicht zusammengehören.
blablabla
User
Beiträge: 6
Registriert: Freitag 7. Oktober 2011, 16:50

was ich mich ganze zeit frage ist noch immer für was brauch ich zB die save_formset funktion?

hab das ganze jetzt mal bei mir ohne dem probiert und das funktioniert genauso...

Mein def save_model sieht zurzeit so aus

Code: Alles auswählen

    def save_model(self, request, obj, form, change):
        instance = form.save(commit=False)
        if not instance.id:
            instance.erstellt_von = request.user
        instance.updated_von = request.user
        instance.save()
        form.save_m2m()
        return instance
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Das save_model in dieser Form ist auch eher kaputt also sonstwas, bitte schau die meine Änderungen im von dir geposteten Link an… save_formset brauchst klarerweise nur für die inlines, wennst keine hast brauchst es nicht…
Antworten