开发者

Django Admin: add inlines dynamically

开发者 https://www.devze.com 2023-02-22 18:11 出处:网络
class MyTemplateAdmin(admin.ModelAdmin): list_display = (\'name\') search_fields = [\'name\'] inlines = [
class MyTemplateAdmin(admin.ModelAdmin):
list_display = ('name')
search_fields = ['name']
inlines = [
    Template1Inline,
    Template2Inline,
    Template3Inline,
]

This works fine. But what I need is to make it dynamic. Whenever the admin adds a new Template to the MyTemplate Model, that needs to开发者_JAVA技巧 be added to the inlines.

Is there a way to do this? Please comment if I am not clear enough on my question. Thanks in advance!


Just Override the admin's 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


I haven't tested this, but in theory you could do:

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']

Hope that helps you out.


In admin.py for the Templates:

class Template1Inline(admin.TabularInline)
  pass

class Template2Inline(admin.TabularInline)
  pass

Then in the admin.py for 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 may not be correct depending on how you have your project setup, but the point is you just import the module that has the Template1Inline classes.


Just a quick idea.

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
        )


I'm not completely sure this is what you are looking for. You want inlines that are different instances of the same model? One way of creating the inlines dynamically is with type() and adding them in 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)
0

精彩评论

暂无评论...
验证码 换一张
取 消