Администратор Django: динамически добавлять строки

#python #django #django-models #django-admin

#питон #джанго #django-модели #django-администратор

Вопрос:

 class MyTemplateAdmin(admin.ModelAdmin):
list_display = ('name')
search_fields = ['name']
inlines = [
    Template1Inline,
    Template2Inline,
    Template3Inline,
]
  

Это работает нормально. Но что мне нужно, так это сделать это динамичным. Всякий раз, когда администратор добавляет новый шаблон в модель MyTemplate, его необходимо добавить во встроенные строки.

Есть ли способ сделать это? Пожалуйста, прокомментируйте, если я недостаточно четко сформулировал свой вопрос. Заранее спасибо!

Ответ №1:

Просто переопределите get_inline_instances администратора.

 def get_inline_instances(self, request, obj=None):
    _inlines = super().get_inline_instances(request, obj=None)
    custom_inline = YourDynamicInline(self.model, self.admin_site)
    _inlines.append(custom_inline)
    return _inlines
  

Ответ №2:

Я не тестировал это, но теоретически вы могли бы сделать:

 class MyTemplateAdmin(admin.ModelAdmin):
    def __init__(self, *args, **kwargs):
        super(MyTemplateAdmin, self).__init__(*args, **kwargs)
        #see if there are new templates
        #and set the inlines list property

    list_display = ('name')
    search_fields = ['name']
  

Надеюсь, это вам поможет.

Ответ №3:

В admin.py для шаблонов:

 class Template1Inline(admin.TabularInline)
  pass

class Template2Inline(admin.TabularInline)
  pass
  

Затем в admin.py для MyTemplateAdmin:

 import sys, inspect, Templates.admin
class MyTemplateAdmin(admin.ModelAdmin):
  list_display = ('name')
  search_fields = ['name']

  def __init__(self, *args, **kwargs):
    inlines = [class_type[1] for class_type in inspect.getmembers(Templates.admin, inspect.isclass)]
    super(MyTemplateAdmin, self).__init__(*args, **kwargs)
  

Templates.admin может быть неверно в зависимости от того, как вы настроили свой проект, но суть в том, что вы просто импортируете модуль, в котором есть Template1Inline классы.

Комментарии:

1. разве inlines здесь не локальная переменная? это ничего не должно менять, вы имели в виду self.inlines?

Ответ №4:

Просто небольшая идея.

 from django.contrib import admin
from mymodule import signals

class MyModuleAdmin(admin.ModelAdmin):

    def add_view(self, *args, **kwargs):
        signals.my_dynamic_inline_hook_signal.send(
            sender = self, 
            inlines = self.inlines,
            args = args, 
            kwargs = kwargs
        )
  

Ответ №5:

Я не совсем уверен, что это то, что вы ищете. Вам нужны встроенные строки, являющиеся разными экземплярами одной и той же модели? Один из способов динамического создания встроенных строк — использовать type() и добавлять их в get_inline_instances()

 class MyTemplateAdmin(admin.ModelAdmin):
    list_display = ('name')
    search_fields = ['name']
    inlines = [some_other_inline]

    def get_inline_instances(self, request, obj=None):
        new_inlines = []
        for inline in (Template, Template2,Template3, ...): # I don't know how you want to get these.
            attrs = {
                'model': MyTemplate,
                # 'extra': 1, Add extra attributes
            }
            # Create a new uninstanciated inline class
            new_inlines.append(type('{}Inline'.format(inline), 
                                      (admin.TabularInline, ), attrs))

        # Add the dynamically created inlines along with the ordinary.
        self.inlines = self.inlines   new_inlines
        return super(CommunityAdmin, self).get_inline_instances(request, obj)