2012-01-19 2 views
1

私はdjangoを初めて使いました。私は過去1ヶ月間単純なアプリケーションを開発していましたが、問題はあります。Djangoでデータベース内の2つのオブジェクトを交換するためのフォーム

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) 

「位置」は単にプレイリスト内の動画の位置を示します。 は、私は(私のmodels.pyから)WeeklyPlaylistと呼ばれる単純なモデルを持っています。 上記のモデルの変更/更新フォーム(admin.pyから):

を使用して、再生リスト内の1つの動画の位置を同じ再生リスト内の別の動画と入れ替える機能を管理者に提供したい
class WeeklyPlaylistAdmin(admin.ModelAdmin): 
    (...) 
    readonly_fields = ('position',) 
    form = WeeklyPlaylistAdminForm 

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

と私は(まだ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 

は基本的に余分な「選択」htmlタグを提供することでした現在のビデオの再生リストに新しい位置を入力し、関連するcで必要なチェックを行うことができるWeeklyPlaylistモデルの変更/更新フォームlean_メソッドを使用して、目的のプレイリスト位置が有効であることを確認します。 これまでのところとても良いです。今、私の問題は次のとおりです。管理者が「保存」ボタンをクリックすると、変更されたオブジェクトと、その位置を交換しているオブジェクトを同時にどのように保存できますか? 「M」はいても、常にfalseですコミット、何らかの理由ことを除いて、完全に罰金だ

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 

:私は、次のコードを使用して、フォームのsave()メソッドでこれをやってみました私が理解していないものです。しかし、結果としてother.save()は呼び出されません。また、コミットの値を調べるifステートメントを削除すると、WeeklyPlaylistAdminFormオブジェクトに保存(コミット= False)することができなくなります。迷惑な... だから、私を助けるための任意の提案? 事前に感謝します! 乾杯! Adrien

+0

あなた.SAVE()署名にコミットkwargを削除し、 '= kwargs.getをコミットやってみてくださいすることはできます(「コミット」、真の)'の代わりに? Djangoの管理内部を排除しようとすると、コミットkwargに割り当てられている偽の第1引数を渡します。私はそれが起こるとは思わないが、深く進む前に排除するものである。 – AdamKG

+0

あなたのコメントをありがとう、AdamKG、あなたが言ったように、結果は同じであり、コミットはまだFalseに設定されています... –

答えて

1

私がDjangoでこれに似たようなことをしたとき、私は別のカテゴリとスワップしているモデルを実装していませんでしたが、リストを再ソートしました。順序5の要素を0に移動すると、0から4までの範囲の順序ですべての以前の要素がシフトされますが、特に順序付けされた要素とのスワップははるかに簡単です。

変更を行う前にモデルの前の位置を保存し、保存が実際に行われる前に保存メソッドで変更されたかどうかを検出します。それが変更されている場合は、現在のモデルを保存し、その位置を持っていて、現在の位置を持たず、その位置を修正するための更新を行うモデルを検索します。うまくいけば、次のコードは、私が何を意味するかを証明助ける必要があります。

class WeeklyPlaylist(models.Model): 
    def __init__(self, *args, **kwargs): 
    super(WeeklyPlaylist, self).__init__(*args, **kwargs) 
    self._position = int(self.position) 

    def save(self, *args, **kwargs): 
    super(WeeklyPlaylist, self).save(*args, **kwargs) 

    # position has changed, so change the position of the element that held the new position now held by this element 
    if int(self.position) != self._position: 
     WeeklyPlaylist.objects.exclude(pk=self.pk).filter(
     position=self.position 
    ).update(position=self._position) 
+0

あなたの返信のために、ドミニク、私はそれがうまくいくはずですが、私は少し気になります並行処理の問題:ケース2のユーザーのユーザーが同じオブジェクトの位置を同時に変更しようとするとどうなりますか? –

関連する問題