2013-08-22 45 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 

瞧:您可以输入任何字段名到任何内嵌于它那场之后添加...这是一个工作位设置,但如果你有几个内联排序可能是一个更清洁的方式...

相关问题