django-admin: la creazione, il salvataggio e relativo un modello m2m
-
09-10-2019 - |
Domanda
Ho due modelli:
class Production(models.Model):
gallery = models.ManyToManyField(Gallery)
class Gallery(models.Model):
name = models.CharField()
Ho il rapporto M2M nel mio produzioni admin, ma voglio che la funzionalità che quando creo una nuova produzione, si crea una galleria di default e il rapporto è stato registrato tra i due.
Finora posso creare la galleria di default sovrascrivendo le produzioni 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)
Ciò crea e salva l'istanza del modello (se non esiste già), ma non so come registrare il rapporto tra i due?
Soluzione
Si registra il rapporto proprio come avete, chiamando add
sul Production
. Il problema è che si sta salvando il Gallery
, ma non il Production
cui save
hai sovrascritto. È necessario chiamare super(...).save(...)
alla fine del vostro 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)
Inoltre, dal momento che hai a che fare con due modelli qui, è necessario utilizzare i segnali di Django per questo, probabilmente, post-Save, che vi darà anche la bandiera created
:
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)
Anche se questo ancora non farà quello che dici che vuoi; se si vuole veramente associare il Gallery
di default con ogni nuovo Production
, ti consigliamo di farlo anche quando non sta creando il Gallery
default:
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)