|
Posted by aangeli |
|
|
Hi there!
I have created a custom model formset class which inherits from the BaseModelFormSet class:
class WeeklyPlaylistAdminFormSet(BaseModelFormSet):
def save(self, commit=True):
instances = super(WeeklyPlaylistAdminFormSet, self).save_existing_objects(commit)
do_something_with_instances(instances)
return instances
which is then used in a custom ModelAdmin class:
class WeeklyPlaylistAdmin(admin.ModelAdmin):
list_display = (schedule_video_name, schedule_screen_name, schedule_year, 'week', 'position', 'position_link')
list_editable = ('position',)
def get_changelist_formset(self, request, **kwargs):
return modelformset_factory(self.model,
self.get_changelist_form(request), extra=0,
fields=self.list_editable,
formset=WeeklyPlaylistAdminFormSet)
However, the problem is that the save() method of the WeeklyPlaylistAdminFormSet does not seem to be called at all, for a reason which I don't understand, even though the objects displayed in the change_list page of the WeeklyPlaylistAdmin class are modified when I change one of the fields in the editable fields. Did I miss something in the way the save() method has to be overriden? Or is there another save_*() method which I should override instead? I've seen that there are several other methods in the BaseModelFormSet class (from django.forms.models): save_existing(), save_existing_objects()... I've tried few of these but it didn't make any difference, and they were not called either... What's even more surprising is that I've also overriden the clean() of the BaseModelFormSet class and it seems to be called correctly... Only the save method is a problem... Any suggestion? Adrien |
|
|
Posted by arwa |
|
|
Hi,
Is possibile for you overload model save method ? This is the simply way... Your overload of get_changelist_formset is correctly done: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L492 The overload of BaseModelFormSet probably also correct. https://code.djangoproject.com/browser/django/trunk/django/forms/models.py#L412 To understand if the save method is run you running put in an exception. Ex: class WeeklyPlaylistAdminFormSet(BaseModelFormSet):
def save(self, commit=True):
instances = super(WeeklyPlaylistAdminFormSet, self).save_existing_objects(commit)
raise Exception('TEST')
do_something_with_instances(instances)
return instances
Make me know if you find the solution. // Robin --- Last Edited by arwa at 2012-01-26 00:56:19 --- |
|
|
Posted by aangeli |
|
|
Thanks for your reply, Robin, I've tried what you said and it confirmed that the save method is not called: when I click on the save button of the change_list page, the modified objects are saved but the exception is not raised! Why is it that the save method does not seem to be called while the clean method works fine?
Adrien |
|
|
Posted by arwa |
|
|
One question: which is your django version?
|
|
|
Posted by aangeli |
|
|
It's 1.3.1
|
|
|
Posted by arwa |
|
|
I don't know what you want to do, but a solution to intercept save in admin is to overload save_model of Admin class
https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L705 Ex:
class WeeklyPlaylistAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# do something
return obj.save() # this call the save model method
Is possibile also work on model: https://code.djangoproject.com/browser/django/trunk/django/db/models/base.py#L453 Ex:
class WeeklyPlaylist(models.Model):
...
def save(self,*args,**kwargs):
obj = super(self.__class__,self).save(*args, **kwargs)
# do something
return obj
I hope that one of these two solution can help you. // Robin |
|
|
Posted by aangeli |
|
|
Thanks Robin, the 'save_model' method is being called, so I could potentially use that one, but what I'd like to do is some sort of cross checking between all the modified objects of the queryset. Maybe I should give more details about the model first:
class WeeklyPlaylist(models.Model): total_num_entries_in_playlist = 8 get_pos_choices = get_integer_choices(1, total_num_entries_in_playlist) sched = models.ForeignKey(Schedule) week = models.IntegerField(choices=get_integer_choices(1, 52)) position = models.IntegerField(choices=get_pos_choices) where 'position' simply indicates the position of a video in a playlist: I'd like to make it possible for the admin to swap the 'position' value of 2 objects of the query set, which implies doing some cross validation to ensure the new position matches an existing object in the queryset (or in the database) and then do the swapping operation. |
|
|
Posted by arwa |
|
|
Now I understand why you want a global validation of all change_list instance.
I have no idea why your method not works. If I have a moment I'm trying to understand better this problem.... Little suggestion: I like this code for field choices. position = models.IntegerField(choices=[(i,str(i) for i in range(1,9)]) // Robin --- Last Edited by arwa at 2012-01-26 04:05:32 --- |
|
|
Posted by aangeli |
|
|
Thanks for your help and suggestion, Robin, looking forward to hearing from you with the solution to my problem
Adrien |


