2013-08-22 12 views
18

次のModelAdminを考えてみましょう。この例では、 "None"フィールドセットとNotesフィールドセットの間にインライン "ブック" UIを表示したいと思います。それは可能ですか?フィールドセット内にDjango管理インラインモデルを表示するにはどうすればよいですか?

class AuthorAdmin(admin.ModelAdmin): 
    inlines = [BookInline] 

    fieldsets = (
      (None, { 
       'fields': ('author_name', 'date_of_birth') 
      }), 
      ('Notes', { 
       'fields': (['notes']) 
      }), 
    ) 

答えて

6

残念ながら、これは(標準テンプレートの)djangoでは不可能です。あなたがchange_form用のテンプレートを見れば、あなたはインラインは常にフィールドセットした後、個別にレンダリングされていることがわかります。 https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html

私が見る唯一の回避策は、あなたが望む順序に関してカスタムテンプレートを作成することです。

+3

ある点ではよりクリーンで、他の点ではより汚れているもう一つの回避策は、jQueryを使用してインラインを移動することです。 –

+1

@andybakには現在の制限がありますが、jqueryを使用するときれいな回避策になります。 – elsadek

+0

親フィールドセットの一部でない場合は、インライン自体のfieldsetを作成することもできます。とにかく私が何をしていたのか。 – radtek

9

ベルトランBortageは、ここに別の解決策を掲載: https://github.com/dezede/dezede/commit/ed13ccaf34494e71fd913fd785c229052f6acdc8https://groups.google.com/forum/#!topic/django-users/yUq2Nvx_4eM

返事が遅れ、私はちょうど私のプロジェクトの一つで、この 問題にかなりきれいな解決策を押したと言うこと。

アイデアは、あなたの ModelAdminの(S)、最初のフィールドセットと 間の順序を指定する「F」と(「フィールドセット」 と「インライン」のための)「I」の文字の反復可能でfieldsets_and_inlines_orderを定義することですインライン。 len(fieldsets_and_inlines_order)< len(fieldsets)+ len(inlines)の場合、残りの部分は元の動作に従います(フィールドセット 、次にすべてのインライン)。

例:あなたは fieldsets_and_inlines_order =( 'F'、 'F'、 'i' は、 'F'、 'I')を定義する、5つのフィールドセットと3つのインラインを持ってはあなたを与える: のfieldsetのfieldsetインラインフィールドセットインラインフィールドセットをフィールドセットインライン希望 助けて、Bertrand

私は考えておく価値がある別のアイデアを持っていました。それぞれのインラインでフィールドセットに読み取り専用のプレースホルダフィールドを作成し、jQueryを使用してインラインを各プレースホルダの場所に移動します。私は別の非常に構築したhttps://code.djangoproject.com/ticket/4848

0

:インラインのこの位置を求めてオープンDjangoの問題がある -

fieldsets = (
     (None, { 
      'fields': (
       ('inline_images',) 
       ('thumbnail_image',), 
       ('inline_authors',) 
       ('title', 'is_active', 'order',) 
      ), 
     }), 
    ) 

readonly_fields = ('inline_images', 'inline_authors') 

inline_images = '<span id='replaceme inline_images'></span>' 
inline_images.allow_tags = True 
inline_authors = '<span id='replaceme inline_authors'></span>' 
inline_authors.allow_tags = True 

もう一つは:このような何かが(jQueryのは、私はまだそれを書いていないよう省略しました)一般的なソリューション...あなたadmin.pyで

があなたのインラインに新しいフィールドを追加します。

class YourModelInline(admin.TabularInline): 
    model = YourModel 
    after_field = "fieldname_of_field_before_inline" 

はその後AdminClasのrender_change_formをカスタマイズインラインを保持しているモデルのS:

class EditModelAdmin(model.ModelAdmin): 
    inlines = [YourModelInline,] 

    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): 
     sorted_inline_formsets = {} 
     inline_admin_formsets = context['inline_admin_formsets'] 
     formsets_to_remove = [] 

     for inline_formset in inline_admin_formsets: 
      if hasattr(inline_formset.opts, 'after_field'): 
       fieldname = inline_formset.opts.after_field 
       if fieldname in sorted_inline_formsets: 
        sorted_inline_formsets[fieldname].append(inline_formset) 
       else: 
        sorted_inline_formsets.update({ 
         fieldname: [inline_formset,] 
        }) 
       formsets_to_remove.append(inline_formset) 
     for inline_formset in formsets_to_remove: 
      inline_admin_formsets.remove(inline_formset) 

     context.update({ 
      'sorted_inline_formsets': sorted_inline_formsets, 
      'inline_admin_formsets': inline_admin_formsets 
     }) 
     return super(EditModelAdmin, self).render_change_form(request, context, add=add, 
                 change=change, obj=obj, form_url=form_url) 

私たちは、キーとしてフィールド名に独自の辞書の中に余分なフィールドを持つすべてのインラインを移動している... それは正しくレンダリングされるようにするには、ファイル/テンプレート/管理者を作成/ /含んでいますfieldset.htmlは、標準のdjangoフィールドセットをオーバーライドします。次の内容のHTML:

{% load custom_filter %} 
 
<fieldset class="module aligned {{ fieldset.classes }}"> 
 
     {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %} 
 
     {% if fieldset.description %} 
 
      <div class="description">{{ fieldset.description|safe }}</div> 
 
     {% endif %} 
 
     {% for line in fieldset %} 
 
      <div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% if not line.has_visible_field %} hidden{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}"> 
 
       {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %} 
 
       {% for field in line %} 
 
        <div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}"{% elif field.is_checkbox %} class="checkbox-row"{% endif %}> 
 
         {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %} 
 
         {% if field.is_checkbox %} 
 
          {{ field.field }}{{ field.label_tag }} 
 
         {% else %} 
 
          {{ field.label_tag }} 
 
          {% if field.is_readonly %} 
 
           <div class="readonly">{{ field.contents }}</div> 
 
          {% else %} 
 
           {{ field.field }} 
 
          {% endif %} 
 
         {% endif %} 
 
         {% if field.field.help_text %} 
 
          <div class="help">{{ field.field.help_text|safe }}</div> 
 
         {% endif %} 
 
        </div> 
 
        {% if field.field.name %} 
 
         {% with field.field.name as fieldname %} 
 
          {% if sorted_inline_formsets|get_dict_value:fieldname != False %} 
 
           {% for inline_admin_formset in sorted_inline_formsets|get_dict_value:fieldname %} 
 
            {% include inline_admin_formset.opts.template %} 
 
           {% endfor %} 
 
          {% endif %} 
 
         {% endwith %} 
 
        {% endif %} 
 
       {% endfor %} 
 
      </div> 
 
     {% endfor %} 
 
    </fieldset>

これは、対応するフィールドの後にソートされたインラインを追加します...今、あなただけのtemplatetags/CUSTOM_FILTERを作成し、Djangoテンプレートで辞書を操作するためのCUSTOM_FILTERを必要としています。 PYおよび追加:

@register.filter 
def get_dict_value(dict, key): 
    if key in dict: 
     return dict[key] 
    else: 
     return False 

出来上がりを:あなたは、そのフィールドの後にそれを追加するために、任意のインラインに任意のフィールド名を入力することができます...それはセットアップに少し作業ですが、あなたは、いくつかのインラインを持っている場合、それはあるかもしれないソートしますよりクリーンな方法...