|
Posted by aangeli |
|
|
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 |
|
|
Posted by arwa |
|
|
On django 1.3, in admin application I use save_model function and not save, so probabily you overload a not correct function.
You find documentation here: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model Make me know if this is the solution. --- Last Edited by arwa at 2012-01-24 09:19:38 --- |


