Django:Admin inline为每个实例形成初始数据

use*_*820 17 django django-admin

我一直在阅读很多,但我似乎无法找到解决方案.

我正在Django中编写一个应用程序,我还在编写管理员端.

我有一个名为"Environments"的模型和一个名为"Servers"的模型,服务器和环境之间存在ForeignKey关系,例如给定环境有多个服务器.

在管理界面中修改环境的"添加"表单时,我使用内联表单来显示将与环境关联的服务器列表,如下所示:

class ServerInline(admin.TabularInline):
    model = Server
    extra = 39

class EnvironmentAdmin(admin.ModelAdmin):
    inlines = [ServerInline]
Run Code Online (Sandbox Code Playgroud)

很简单吧?

我想要做的是使用默认值预填充服务器内联表单,我已经能够使用相同的值预先填充它们:

class ServerInlineAdminForm(forms.ModelForm):
    class Meta:
        model = Server

    def __init__(self, *args, **kwargs):
        super(ServerInlineAdminForm, self).__init__(*args, **kwargs)
        self.initial['name']='Testing'

class ServerInline(admin.TabularInline):
    form = ServerInlineAdminForm
    model = Server
    extra = 39

class EnvironmentAdmin(admin.ModelAdmin):
    inlines = [ServerInline]
Run Code Online (Sandbox Code Playgroud)

但这不是我想要的,我希望能够使用列表中的39个不同值初始化39个服务器表单实例.最好的办法是什么?

谢谢!

frn*_*nhr 9

这是我的实现,感谢Steven的想法.

全部在admin.py中:

class SecondaryModelInline(admin.ModelAdmin):
    model = SecondaryModel
    formset = SecondaryModelInlineFormSet

    def get_formset(self, request, obj=None, **kwargs):
        formset = super(SecondaryModelInline, self).get_formset(request, obj, **kwargs)
        formset.request = request
        return formset

    def get_extra(self, request, obj=None, **kwargs):
        extra = super(SecondaryModelInline, self).get_extra(request, obj, **kwargs)
        something = request.GET.get('something', None)
        if something:
            extra = ... figure out how much initial forms there are, from the request ...
        return extra
Run Code Online (Sandbox Code Playgroud)

之前的某个地方,也是在admin.py中,这个:

class SecondaryModelInlineFormSet(forms.models.BaseInlineFormSet):
    model = SecondaryModel

    def __init__(self, *args, **kwargs):
        super(SecondaryModelInlineFormSet, self).__init__(*args, **kwargs)            
        if self.request.GET.get('something', None):
            # build your list using self.request
            self.initial=[{'field_a': 'A', ...}, {}... ]
Run Code Online (Sandbox Code Playgroud)


Ste*_*ven 7

不知道确切为什么要这样做,但是也许可以创建一个modelformset:

from django.forms.models import BaseModelFormSet
class ServerFormSet(BaseModelFormSet):
    def __init__(self, *args, **kwargs):
        super(ServerFormSet, self).__init__(*args, **kwargs)
        self.initial = [{ 'name': 's1', }, {'name': 's2'},] # supply your list here
Run Code Online (Sandbox Code Playgroud)

并将其设置在您的内联中:

class ServerInline(admin.TabularInline):
    form = ServerInlineAdminForm
    model = Server
    extra = 39
    formset = ServerFormSet
Run Code Online (Sandbox Code Playgroud)

我还没有尝试过。

参见:https : //docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.formset

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#providing-initial-values

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#using-initial-data-with-a-formset


use*_*820 4

我意识到我自己解决了这个问题并没有在这里回答。

我最终所做的是重写环境类 save_model 方法,而不是使用管理表单。

我会更好地解释一下:

我有一个环境对象和一个服务器对象。一个环境有许多服务器,这些服务器通过服务器对象的外键链接到该环境。我的目标是在环境创建过程中填充与环境关联的服务器。为了能够做到这一点,我所做的是覆盖环境对象的 save_model 方法,执行 obj.save() 并随后创建指向此环境的服务器对象,然后再次 obj.save() 。为什么后来呢?因为我无法将新创建的服务器与尚不存在的环境关联起来。让我知道是否有人对他的实际代码感兴趣。