2013-08-22 169 views
18

請考慮以下ModelAdmin。在這種情況下,我希望在「無」字段集和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

如果不是父字段集的一部分,您也可以爲內聯本身創建字段集。多數民衆贊成在反正之後。 – radtek

9

伯特蘭Bortage張貼在這裏另一種解決方案:https://groups.google.com/forum/#!topic/django-users/yUq2Nvx_4eM

逾期答覆說,我只是把一個相當乾淨地解決了這個問題 在我的項目之一: https://github.com/dezede/dezede/commit/ed13ccaf34494e71fd913fd785c229052f6acdc8

的想法是在你 的ModelAdmin(S),「f」和「i」的字符(「字段集」 和「內聯」)的一個可迭代,用於指定所述第一字段集和 之間的順序來定義fieldsets_and_inlines_order內聯。如果len(fieldsets_and_inlines_order)len(fieldsets)+ len(inline),其餘的遵循原始行爲(字段集 第一,然後全部內聯)。

實施例:你有5個字段集和3個內聯,定義 fieldsets_and_inlines_order =( 'F', 'F', 'I', 'F', 'I')會給你: 字段集字段集直列字段集內聯字段集fieldset內聯希望 它有幫助,Bertrand

我有另一個值得考慮的想法。在您的字段集中爲每個內聯字段創建只讀佔位符字段,然後使用jQuery將內聯移動到每個佔位符的位置。像這樣的東西(jQuery的省略,因爲我沒有寫它尚未):

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 

一兩件事 - 有一個開放的Django問題詢問該定位內聯:https://code.djangoproject.com/ticket/4848

0

我構建另一個很通用的解決方案......

在你admin.py一個新字段添加到您的內聯:

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

然後自定義AdminClas的render_change_form該模型第持有的內聯:

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>

這將相應的字段後面添加排序內聯......現在,你只需要在Django的模板字典工作custom_filter,創建templatetags/custom_filter。 PY並添加:

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

瞧:您可以輸入任何字段名到任何內嵌於它那場之後添加...這是一個工作位設置,但如果你有幾個內聯排序可能是一個更清潔的方式...

相關問題