Django: Zugriff auf ManyToManyField Objekte nach dem Speichern
-
25-09-2019 - |
Frage
Dies ist verwirrend ich ... Wenn ich mein Modell zu speichern, sind die Buchobjekte unverändert. Aber wenn ich die Rechnung öffnen und wieder speichern, werden die Änderungen vorgenommen. Was mache ich falsch?
class Invoice(models.Model):
...
books = models.ManyToManyField(Book,blank=True,null=True)
...
def save(self, *args, **kwargs):
super(Invoice, self).save(*args, **kwargs)
for book in self.books.all():
book.quantity -= 1
if book.quantity == 0:
book.sold = True;
book.save()
Edit: Ich habe versucht, das post_save Signal verwendet, aber es funktioniert auf die gleiche Art und Weise. speichern Keine Änderungen auf dem ersten, ändert das zweite Mal gespeichert.
Update: Es scheint, mit diesem Code gelöst werden:
class InvoiceAdmin(admin.ModelAdmin):
...
def save_model(self, request, obj, form, change):
obj.save()
for bk in form.cleaned_data['books']:
book = Book.objects.get(pk=bk.id)
book.quantity -= 1
if book.quantity == 0:
book.sold = True;
book.save()
Lösung
Dies ist, wie ich um diesen arbeitete, in der Tat rätselhaft, Verhalten. Schließen Sie einen Signalempfänger an models.signals.m2m_changed Fall ist dies get jedes Mal, wenn ein m2m Feld ausgelöst wird geändert. Die Inline-Kommentare erklären, warum.
class Gig(models.Model):
def slugify(self):
# Add venue name, date and artists to slug
self.slug = slugify(self.venue.name) + "-"
self.slug += self.date.strftime("%d-%m-%Y") + "-"
self.slug += "-".join([slugify(artist.name) for artist in self.artists.all()])
self.save()
@receiver(models.signals.m2m_changed, sender=Gig.artist.through)
def gig_artists_changed(sender, instance, **kwargs):
# This callback function get's called twice.
# 1 first change appears to be adding an empty list
# 2nd change is adding the actual artists
if instance.artist.all() and not instance.slug:
instance.slugify()
Andere Tipps
Das ist, weil m2m Beziehung gespeichert wird nach dem Modell zu speichern, um PK von Eltern-Objekt zu erhalten. In Ihrem Fall Sekunde speichern Arbeiten zu erwarten, da Modell bereits PK und zugehörige Bücher aus dem ersten hat speichern (in einem Signal gemacht wird).
Ich habe nicht die Lösung noch nicht gefunden, beste Wette ist, um Ihre Änderungen zu tun im Admin-Ansicht , denke ich.