Django-fr

Forum

  • Accueil
  • » Django-fr
  • » Formulaire pour intervertir les positions de 2 objets

#1 19-01-2012 16:01:14

aangeli
Membre
Inscription : 19-01-2012
Messages : 2

Formulaire pour intervertir les positions de 2 objets

Bonjour!

J'apprends à utiliser et django et j'ai commencé à développer une app web simple il y a 1 mois, mais j'ai un problème, quelque chose que je n'arrive pas à faire.

J'ai un modèle appelé WeeklyPlaylist (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)

où 'position' désigne la position d'une vidéo dans une playlist.

J'aimerais permettre à l'admin d'intervertir les positions de 2 vidéos faisant partie d'une même playlist, via le formulaire de modification/mise à jour du modèle ci-dessus (admin.py):

class WeeklyPlaylistAdmin(admin.ModelAdmin):
    (...)
    readonly_fields = ('position',)
    form = WeeklyPlaylistAdminForm

    def get_changelist_form(self, request, obj=None, **kwargs):
        return WeeklyPlaylistAdminForm

J'ai défini un formulaire spécial pour ce type d'objet (tjs dans 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

Ce que j'ai en tête consiste simplement à ajouter un tag html 'select' au formulaire de changement/mise à jour du modèle WeeklyPlaylist où l'on pourrait entrer la nouvelle position de la vidéo dans la playlist, avec les vérifications nécessaires dans la méthode clean_ correspondante pour s'assurer que la position désirée est vallide.

Jusqu'ici tout va bien. Mon problème est le suivant : lorsque l'admin clique sur 'save', comment puis-je simultanément sauvegarder l'objet modifié ainsi que celui avec lequel il échange sa position dans la playlist? J'ai essayé de faire ça dans la méthode save() du formulaire, avec le code ci-dessous :

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

Mais pour une raison que j'ignore, 'commit' est tjs 'False' lorsque la méthode est appelée, alors que 'm' est bien mis à jour dans la BDD après la modification! Du coup, comme 'other.save()' n'est pas appelé, l'autre objet n'est pas mis à jour, et les 2 objets se retrouvent avec la même position! Et si j'enlève le 'if' qui vérifie la valeur de 'commit', il me sera impossible par la suite de faire un save(commit=False) sur les objets de type WeeklyPlaylistAdminForm, ce qui est pénalisant...

Merci d'avance pour votre aide!
Adrien

Hors ligne

  • Accueil
  • » Django-fr
  • » Formulaire pour intervertir les positions de 2 objets

Pied de page des forums