2017-09-24 9 views
0

crate属性を持つForeignKeyCrateモデルのモデルがあります。 Crateモデルには、というという属性(現在保持できるジャーの数)jarscapacity属性(保持できるjarの数)があります。管理アクションの中間ページの動的ドロップダウン

私は複数のジャーを新しいクレートに移動する管理アクションを持っています。中間ページを使用して宛先枠を選択します。現在、すべてのクレートがドロップダウンリストに表示されていますが、リストに表示されているクレートを、選択されたジャー数の部屋に制限したいとします。どうやって?ここで

admin.pyから管理者のアクションです:

class MoveMultipleJarsForm(forms.Form): 
    # This needs to somehow be restricted to those crates that have room 
    dest = forms.ModelChoiceField(queryset=Crate.objects.all().order_by('number')) 

def move_multiple_jars(self, request, queryset): 
    form = None 

    if 'apply' in request.POST: 
     form = self.MoveMultipleJarsForm(request.POST) 

     if form.is_valid(): 
      dest = form.cleaned_data['dest'] 

      count = 0 
      for jar in queryset: 
       jar.crate = dest 
       jar.save() 
       count += 1 

      plural = '' 
      if count != 1: 
       plural = 's' 

      self.message_user(request, "Successfully moved %d jar%s to %s" % (count, plural, dest)) 
      return HttpResponseRedirect(request.get_full_path()) 
    if not form: 
     form = self.MoveMultipleJarsForm() 

    return render(request, 'admin/move_multiple_jars.djhtml', { 
     'jars': queryset, 
     'move_multiple_jars_form': form, 
     }) 

move_multiple_jars.short_description = "Move multiple jars to new crate" 

答えて

0

は、Python開発者スラックサーバー上のlaidibugの助けを借りて、私は解決策を考え出すことができました。

class MoveMultipleJarsForm(forms.Form): 
    dest = forms.ModelChoiceField(Crate.objects.none()) 

    def __init__(self, *args, **kwargs): 
     count = kwargs.pop('count') 
     super().__init__(*args, **kwargs) 
     self.fields['dest'].queryset = Crate.objects.annotate(room=F('capacity')-Sum(Case(When(jar__is_active=True, then=1), default=0), output_field=IntegerField())).filter(room__gte=count).order_by('number') 


def move_multiple_jars(self, request, queryset): 
    form = None 

    if 'apply' in request.POST: 
     form = self.MoveMultipleJarsForm(request.POST) 

     if form.is_valid(): 
      dest = form.cleaned_data['dest'] 

      count = 0 
      for jar in queryset: 
       jar.crate = dest 
       jar.save() 
       count += 1 

      plural = '' 
      if count != 1: 
       plural = 's' 

      self.message_user(request, "Successfully moved %d jar%s to %s" % (count, plural, dest)) 
      return HttpResponseRedirect(request.get_full_path()) 
    if not form: 
     form = self.MoveMultipleJarsForm(count=queryset.count()) 

    return render(request, 'admin/move_multiple_jars.djhtml', { 
     'jars': queryset, 
     'move_multiple_jars_form': form, 
     }) 

move_multiple_jars.short_description = "Move multiple jars to new crate" 

溶液第一歩は、宛先箱のリストを変更することができ、初期化値としてクエリセット内の瓶の数を渡すためにフォームクラスを変更することでした。私はSubqueryOuterRefで90%のソリューションを持っていましたが、アクティブなジャーのないクレートは処理できませんでした。私はこの質問で受け入れられた答えに行った:How to filter objects for count annotation in Django?奇妙なことに、私の90%のソリューションは、Django 1.11のソリューションに似ていますが、私は彼らが参加していないケースについて心配していないと思います。その質問で別の議決権を与えました。もし私がそれを最初に見たなら、私はこの質問を投稿しなくてもいいかもしれないからです。

関連する問題