2π
β
I personally stay away from using the Admin pages once you need real business logic, but here is the answer:
If you only need to do this from the Admin pages, you can simply overwrite the Admin save function
class ParentAdmin(admin.ModelAdmin):
list_display = ('id', 'parent', )
def save_model(self, request, obj, form, change):
obj.save()
for c in obj.child_set.all():
if c.granparent != obj.grandparent:
c.grandparent = obj.grandparent
c.save()
admin.site.register(Parent, ParentAdmin)
But if you would like to ensure the Child is always updated, regardless of who did the save(), you can
1.- Overwrite the modelβs save() function (but this may create a circular dependency if your models are in different files:
class Parent(models.Model):
grandparent = models.ForeignKey(GrandParent, null=True, blank=True, default=None)
def save(self, *args, **kwargs):
for c in self.child_set.all():
if c.granparent != self.grandparent:
c.grandparent = self.grandparent
c.save()
super(Parent, self).save(*args, **kwargs)
2.- To avoid circular dependencies, you can use a signal to catch the save and act on it
from django.db.models.signals import post_save
from django.dispatch import receiver
class Child(models.Model):
parent = models.ForeignKey(Parent, null=True, blank=True, default=None)
grandparent = models.ForeignKey(GrandParent, null=True, blank=True, default=None)
@receiver(post_save, sender=Parent)
def post_save_parent_callback(sender, **kwargs):
parent = kwargs['instance']
for c in parent.child_set.all():
if c.granparent != parent.grandparent:
c.grandparent = parent.grandparent
c.save()
Hope this helps.
π€dkarchmer
Source:stackexchange.com