I’ve got an admin form with a couple of inlines for displaying m2m fields, like so:
class ArticleAdmin(admin.ModelAdmin):
form = ArticleCustomAdminForm
inlines = (SpecificGemInline, SuiteInline,)
Base class looks something like that:
class Article(models.Model):
article_code = models.CharField(max_length=15)
gems = models.ManyToManyField(Gem, through='SpecificGem')
Model has a special field article_code that should aggregate some data from m2m fields represented in both inlines, so I’ve written a function create_code(instance) that does so by accessing model instance fields directly, something like that:
def create_code(instance):
article_code_part1 = SpecificGem.objects.filter(article=instance)
article_code_part2 = instance.suite_set.all()
instance.article_code = #do something with both parts
The problem is, when I call this function from overriden ModelAdmin’s save_model() or model’s save() functions, following instance m2m fields produces outdated results. Even retarded example below wouldn’t help:
class ArticleAdmin(admin.ModelAdmin):
#...
def save_model(self, request, obj, form, change):
obj.save()
create_code(obj)
obj.save()
When I get into InlineFormset’s clean() method, I have access to its forms’ data so I could figure out a part of article_code even without actual saving… but I have two inlines.
So how do I find the topmost save method, so I could call my aggregation function after all models are validated and saved to db?
In order to catch changes to a
ManyToManyField, you need to hook up them2m_changedsignal. You might want to have a look at the documentation for signals in general and the m2m_changed signal in particular.