2017-08-08 5 views
1

KeywordというモデルとStatementというモデルがあります。私は、ステートメントの追加や変更のためのフォームをカスタマイズしています。各KeywordオブジェクトはStatementオブジェクトとm2m(多対多)の関係を持ち、関連付けるキーワードをユーザーが選択できるようにしたいと考えました。多くのKeywordオブジェクトがあるので、m2mフィールドのデフォルトのウィジェットは私の場合は役に立たないので、それよりも優れたものが必要でした。私は必要な調整を得るためにFilteredSelectMultipleウィジェットを使用しました。djangoインラインでカスタム管理フォームに緑色のプラス記号を追加していますか?

ここにそのコードがあります。 forms.py

class StatementForm(forms.Modelform): 
     statement_keywords = forms.ModelMultipleChoiceField(
      queryset=Keyword.objects.all(), 
      required=False, 
      widget=FilteredSelectMultiple(
       verbose_name='Keywords Associated with Statement', 
       is_stacked=False 
      ) 
     ) 
     class Meta: 
      model = Statement 
     def __init__(self, *args, **kwargs): 
      super(StatementForm, self).__init__(*args, **kwargs) 
      if self.instance.pk: 
       self.fields['statement_keywords'].initial = self.instance.keyword_set.all() 

     def save(self, commit=True): 
      statement = super(StatementForm, self).save(commit=False) 
      if commit: 
      statement.save() 
      if statement.pk: 
       statement.keyword_set = self.cleaned_data['keyword'] 
      self.save_m2m() 

    return statement 

admin.py

class KeywordInline(admin.TabularInline): 
     model = Keyword.statement.through 
    class StatementAdmin(admin.ModelAdmin): 
     list_display = ('statement_id', 'title', 'author', 'released_by', 'issue_date', 'access', 'full_text',) 
     list_filter = (StatementListFilter, 'released_by', 'issue_date', 'access',) 
     search_fields = ('statement_id', 'title', 'author', 'issue_date',) 
     inlines = [ KeywordInline,] 

だから今、私は私が欲しかっただけのように、私のインラインのfilter_horizo​​ntalメニューを持っています。しかし、1つの問題があります:新しいキーワードを追加するプラス記号はありません。

これを解決するにはRelatedFieldWidgetWrapperが必要であることがわかりました。私はこれを使用している人の例がたくさん見つかりました。しかし、私は自分の状況に合ったものを見つけることができませんでした。私が今直面している最も直面する問題は、「rel」パラメータに何かを挿入しようとすることです。 "rel"パラメータは、一般的に "関連する2つのモデルの関係"を定義しています。http://dashdrum.com/blog/2012/07/relatedfieldwidgetwrapper/

私はこの関係について何を示すべきか、それを示す方法はわかりません。インラインで作業しています。だから、私は実際には "キーワード"と呼ばれるフィールドで作業していません。KeywordStatementの間のm2m関係を逆に調べています。だから関係を説明するために名前が何を意味するのか分かりません。

私が見つけたすべての例では、この状況で何をすべきかについて実際には話していませんでした。ほとんどの例は、モデルの1つから関心のあるフィールドを簡単に取得し、そのタイプまたは関係を取得しますが、インラインモデルと逆の関係では、必ずしもそうすることはできません。

+0

あなたは 'extra'と' max_num'旅館あなたのインラインを設定しようとしましたか? –

+0

はありませんでした。私はしばらくするだろうが...これらの特性はこの文脈で何をしているのだろうか? –

+0

'extra'はデフォルトで表示される余分なインライン数を定義します。 'max_num'はインラインの数を制限します。したがって、もしあなたのデフォルト値 'max_num'がデフォルト値の' extra'より小さいなら、追加のインラインを追加することはできません。あなたの問題は、あなたのmodelFormが解決策ではないかもしれないからですが、試してみてください。私は、 –

答えて

0

私は多くのリレーションと、あなたが記述しているようなインラインモデルのカスタムウィジェットで終わるように管理しました。あなたがあなたの質問にmodels.pyを提供しないと、あなたもあなたのコードでこのoccasion-情報のための余分な-unnecessaryを持っているので、ここでthis answerthis postからインスピレーションを受け

は私のモデルを使用した結果です。

models.py

class MasterModel(models.Model): 
    pass 


class ThirdModel(models.Model): 
    pass 


class InlineModel(models.Model): 
    ''' 
     It should also be working with a ForeignKey 
     but I have not tested it. 
    ''' 
    master_key = models.OneToOneField(MasterModel) 
    the_field = models.ManyToManyField(ThirdModel) 

forms.py

from django.contrib.admin import site as admin_site 
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper 


class InlineModelForm(forms.Modelform): 
    the_field = forms.ModelMultipleChoiceField(
     queryset=ThirdModel.objects.all(), 
     required=False, 
     widget=(
      <the_custom_widget with attributes etc> 
     ) 
    ) 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.fields['the_field'].widget = (
      RelatedFieldWidgetWrapper( 
       self.fields['the_field'].widget, 
       self.instance._meta.get_field('the_field').rel,    
       admin_site, 
      ) 
     ) 

    class Meta: 
     model = InlineModel 
     fields = '__all__' 

admin.py:

class InlineModelAdminInline(admin.TabularInline): 
    model = InlineModel 
    form = InlineModelForm 


@admin.register(MasterModel) 
class MasterModelAdmin: 
    inlines = (InlineModelAdminInline,) 


@admin.register(InlineModel) 
class InlineModelAdmin: 
    form = InlineModelForm 


@admin.register(ThirdModel) 
class ThirdModelAdmin: 
    pass 
関連する問題