22

我已经阅读了很多,但我似乎无法找到解决方案。

我正在用 Django 编写应用程序,但我仍在编写管理端。

我有一个名为“环境”的模型和一个名为“服务器”的模型,服务器和环境之间存在外键关系,例如给定的环境有多个服务器。

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

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

class EnvironmentAdmin(admin.ModelAdmin):
    inlines = [ServerInline]

很简单吧?

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

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]

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

谢谢!

4

6 回答 6

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

之前的某个地方,也在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', ...}, {}... ]
于 2014-06-27T23:41:20.407 回答
8

不确定您为什么要这样做,但也许您可以创建一个模型表单集:

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

并将其设置为您的内联:

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

我还没有尝试过。

请参阅: 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

于 2012-09-12T16:01:59.887 回答
4

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

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

我会解释得更好一点:

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

于 2012-11-07T11:42:35.507 回答
3

我还没有尝试过,但是由于生成的额外表单是必不可少的 Django Formsets,因此您需要做的是将初始数据绑定到此处的文档中解释的表单集。

我刚刚阅读了文档,看起来您可以在 inlineadmin 中定义自己的表单集,然后如上所述,使用列表中的数据预填充表单集。我认为您可以通过将预填充代码放在类的init方法中来实现这一点。

我知道这不是一个非常详尽的解释,但我发现这个问题很有趣,并查阅了文档并认为也许我可以为您指明下一步要尝试的正确方向。

于 2012-09-12T15:54:02.360 回答
2

好吧,我想评论frnhr的答案,但没有足够的声誉,所以:

答案对我有用,我只需要遍历表单集中的表单并为每个表单设置初始数据:

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
            for form in self:
                form.initial = {'field_a':'A',...} #This is what I changed
            self.initial=[{'field_a': 'A', ...}, {}... ]
于 2014-09-18T12:53:31.617 回答
1

user在从request.userforStackedInline和预填充的情况下,它对我有用TabularInline

def save_formset(self, request, form, formset, change):
    for form in formset.forms:
        form.instance.user = request.user
    formset.save()
于 2016-06-07T07:38:29.320 回答