Ich habe ein Modell, das einen Betreffnamen und deren Initialen enthalten soll (die Daten sind etwas anonymisiert und werden durch Initialen verfolgt).
Im Moment habe ich geschrieben
class Subject(models.Model):
name = models.CharField("Name", max_length=30)
def subject_initials(self):
return ''.join(map(lambda x: '' if len(x)==0 else x[0],
self.name.split(' ')))
# Next line is what I want to do (or something equivalent), but doesn't work with
# NameError: name 'self' is not defined
subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials)
Wie in der letzten Zeile angegeben, würde ich es vorziehen, wenn die Initialen tatsächlich als Feld (unabhängig vom Namen) in der Datenbank gespeichert werden, dies wird jedoch mit einem Standardwert initialisiert, der auf dem Namensfeld basiert. Ich habe jedoch Probleme, da Django-Modelle kein "Selbst" zu haben scheinen.
Wenn ich die Zeile in subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials)
ändere, kann ich die Synchronisierung durchführen, aber keine neuen Themen erstellen.
Ist dies in Django möglich, wenn eine aufrufbare Funktion einem Feld einen Standardwert gibt, der auf dem Wert eines anderen Felds basiert?
(Für Neugierige ist der Grund, warum ich meine Geschäftsinitialen separat trennen möchte, in seltenen Fällen, in denen seltsame Nachnamen andere als die von mir verfolgten haben. ZB hat jemand anderes entschieden, dass die Initialen von Betreff 1 mit dem Namen "John O'Mallory" lauten "JM" statt "JO" und möchte es als Administrator bearbeiten.)
quelle
super().save(*args, **kwargs)
(ohne dieSubject, self
Argumente) wie im Beispiel in der Dokumentation aufrufen können .Ich weiß nicht, ob es einen besseren Weg gibt, aber Sie können einen Signalhandler für das
pre_save
Signal verwenden :quelle
post_save
stattpre_save
.**kwargs
Argument fehlt , das alle Empfängerfunktionen laut docs.djangoproject.com/de/2.0/topics/signals/… haben sollten .save()
, die möglicherweise in Überschreiben geändert wurde__init__
, ist besser, da sie expliziter ist.Mit Django-Signalen kann dies ziemlich früh erfolgen, indem das
post_init
Signal vom Modell empfangen wird .Das
post_init
Signal wird von der Klasse gesendet, sobald die Instanz initialisiert wurde. Auf diese Weise erhält die Instanz einen Wert für,name
bevor getestet wird, ob ihre nicht nullbaren Felder festgelegt sind.quelle
save()
, die möglicherweise in Überschreiben geändert wurde__init__
, ist besser, da sie expliziter ist.Als alternative Implementierung der Antwort von Gabi Purcaru können Sie auch
pre_save
über denreceiver
Dekorateur eine Verbindung zum Signal herstellen :Diese Empfängerfunktion verwendet auch die
**kwargs
Platzhalter-Schlüsselwortargumente, die alle Signalhandler gemäß https://docs.djangoproject.com/de/2.0/topics/signals/#receiver-functions verwenden müssen .quelle