django-admin: Erstellen, Speichern und beziehen eine m2m-Modell
-
09-10-2019 - |
Frage
Ich habe zwei Modelle:
class Production(models.Model):
gallery = models.ManyToManyField(Gallery)
class Gallery(models.Model):
name = models.CharField()
Ich habe die m2m-Beziehung in meinen Produktionen admin, aber ich möchte, dass die Funktionalität, dass, wenn ich eine neue Produktion erstellen, wird eine Standardstrecke erstellt und die Beziehung zwischen den beiden registriert ist.
Bisher kann ich die Standard-Galerie erstellen, indem sie die Produktion zu überschreiben speichern:
def save(self, force_insert=False, force_update=False):
if not ( Gallery.objects.filter(name__exact="foo").exists() ):
g = Gallery(name="foo")
g.save()
self.gallery.add(g)
Das erstellt und speichert die Modellinstanz (wenn es nicht bereits vorhanden ist), aber ich weiß nicht, wie die Beziehung zwischen den beiden?
registrierenLösung
Sie haben die Beziehung registrieren, wie Sie haben, von add
auf dem Production
aufrufen. Das Problem ist, dass Sie die Gallery
sind zu speichern, aber nicht die Production
deren save
Sie haben außer Kraft gesetzt. Sie müssen Anruf super(...).save(...)
am Ende Ihres save
:
def save(self, force_insert=False, force_update=False):
if not ( Gallery.objects.filter(name__exact="foo").exists() ):
g = Gallery(name="foo")
g.save()
self.gallery.add(g)
super(Production, self).save(force_insert=force_insert, force_update=force_update)
Darüber hinaus, da Sie sind den Umgang mit zwei Modellen hier, sollten Sie Djangos Signale für diese, wahrscheinlich post-save , die auch Sie die created
Flagge geben:
def create_default_gallery(sender, instance, created, **kwargs):
if created and not Gallery.objects.filter(name__exact="foo").exists():
g = Gallery(name="foo")
g.save()
instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)
Auch wenn dies noch nicht tun, was Sie sagen, Sie wollen; wenn Sie wirklich der Standard Gallery
mit jedem neuen Production
zuordnen mögen, sollten Sie es auch tun, wenn Sie nicht den Standard Gallery
erstellen:
def create_default_gallery(sender, instance, created, **kwargs):
if created:
g = Gallery.objects.get_or_create(name__exact="foo")
g.save()
instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)