| Name | aangeli |
|---|---|
| Email Address | n/a |
| Posts | 6 |
-
- 2012-01-26 04:22:41
- Re: save() method of a BaseModelFormSet object not called
- Board » Django Standard Library » Admin
-
Thanks for your help and suggestion, Robin, looking forward to hearing from you with the solution to my problem
Adrien
-
- 2012-01-26 03:54:25
- Re: save() method of a BaseModelFormSet object not called
- Board » Django Standard Library » Admin
-
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.
-
- 2012-01-26 02:54:40
- Re: save() method of a BaseModelFormSet object not called
- Board » Django Standard Library » Admin
-
It's 1.3.1
-
- 2012-01-26 02:00:43
- Re: save() method of a BaseModelFormSet object not called
- Board » Django Standard Library » Admin
-
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
-
- 2012-01-25 09:25:25
- save() method of a BaseModelFormSet object not called
- Board » Django Standard Library » Admin
-
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
-
- 2012-01-24 02:46:49
- Form to swap 2 objects in database with Django
- Board » Django Standard Library » Admin
-
I'm new to django and I've been developping a simple application for the past month or so, but I have a problem, something I did not manage to do. I have a simple model called WeeklyPlaylist (from my models.py):
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 provide the admin with the ability to swap the position of one video in a playlist with another video in that same playlist, through the change/update form of the model above (from my admin.py):
class WeeklyPlaylistAdmin(admin.ModelAdmin): (...) readonly_fields = ('position',) form = WeeklyPlaylistAdminForm def get_changelist_form(self, request, obj=None, **kwargs): return WeeklyPlaylistAdminForm
and I'm defining my own form for this object (still from admin.py):
class WeeklyPlaylistAdminForm(ModelForm): class Meta: model = WeeklyPlaylist fields = ('position',) swap_with_position = forms.IntegerField(widget=forms.Select(choices=WeeklyPlaylist.get_pos_choices)) def clean_swap_with_position(self): swap_with_position = self.cleaned_data['swap_with_position'] instance = getattr(self, 'instance', None) if instance and instance.id and swap_with_position == self.instance.position: raise forms.ValidationError("You must specify a different position than the actual one.") # select the database obj to swap position with other = WeeklyPlaylist.objects.filter(sched__screen__name=self.instance.sched.screen.name, sched__year__exact=self.instance.sched.year, week=self.instance.week, position=swap_with_position) if other.count() != 1: raise forms.ValidationError("The desired position does not correspond to any existing WeeklyPlaylist entry.") return swap_with_position
What I had in my mind basically was to provide an extra 'select' html tag to the admin in the change/update form of the WeeklyPlaylist model where he could enter the new position in the playlist for the current video, with the necessary checks in the associated clean_ method to make sure the desired playlist position is valid. So far so good. Now, my problem is the following: when the admin clicks on the 'save' button, how can I simultaneously save the modified object, and the one it is exchanging its position with? I've tried doing this in the save() method of the form, using the following code:
def save(self, commit=True, *args, **kwargs): m = super(WeeklyPlaylistAdminForm, self).save(commit=False, *args, **kwargs) cleaned_data = self.cleaned_data swap_with_position = cleaned_data.get("swap_with_position") if commit: # select the database obj to swap position with other = WeeklyPlaylist.objects.get(sched__screen__name=m.sched.screen.name, sched__year__exact=m.sched.year, week=m.week, position=swap_with_position) m.position, other.position = other.position, m.position m.save() other.save() return m
That seems perfectly fine, except that for some reason, commit is always false, even though 'm' is saved after the operation is finished, which is something I don't understand. But as a consequence, other.save() is never called, and if I remove the if statement checking the value of commit, I won't be able to do a save(commit=False) on the WeeklyPlaylistAdminForm objects, which can be annoying... So, any suggestions to help me? Many thanks in advance! Cheers! Adrien


