Note that there are some explanatory texts on larger screens.

plurals
  1. POForm to swap 2 objects in database with Django
    primarykey
    data
    text
    <p>I'm new to django and I've been developing 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):</p> <pre><code>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) </code></pre> <p>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):</p> <pre><code>class WeeklyPlaylistAdmin(admin.ModelAdmin): (...) readonly_fields = ('position',) form = WeeklyPlaylistAdminForm def get_changelist_form(self, request, obj=None, **kwargs): return WeeklyPlaylistAdminForm </code></pre> <p>and I'm defining my own form for this object (still from admin.py):</p> <pre><code>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 </code></pre> <p>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:</p> <pre><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 </code></pre> <p>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</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload