Django的:管理在线表单的初始数据为每个实例(Django: Admin inline form

2019-06-28 06:05发布

我一直在阅读了很多,但我似乎并没有能够解决弄清楚了这一点。

我正在写在Django的应用程序,我还在写管理员的一面。

我有一个名为“环境”模型和一个名为“服务器”的模式,有服务器和环境之间的一个ForeignKey关系,例如一个给定的环境有几个服务器。

当修改在管理界面中的“添加”形式的环境我用一个内嵌的形式是能够直观地将相关环境,这样的服务器列表:

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服务器的表单实例。 什么是做到这一点的最好办法?

谢谢!

Answer 1:

下面是我的实现, 得益于史蒂芬的想法 。

所有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', ...}, {}... ]


Answer 2:

不知道究竟为什么要做到这一点,但也许你可以创建一个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

并将此在您的内联:

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



Answer 3:

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

我终于做是重写环境类save_model方法,而不是使用管理形式。

我会更好地解释一下:

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



Answer 4:

我还没有试过,但由于产生额外的形式是必不可少的Django表单集,你需要做的是绑定初始数据,其在文档解释了表单集在这里 。

我只是通过文档阅读,它看起来像你可以定义自己的表单集你inlineadmin内 ,然后如上面提到的,预填充表单集从您的列表数据。 我想你可以通过将预填充代码在你的类的init方法实现这一目标。

我知道这是不是一个非常复杂的解释,但我发现这个问题有意思,抬头的文档,并想也许我可以指出你在什么尝试下一个正确的方向。



Answer 5:

嗯,我想对frnhr的回答发表评论,但没有足够的声誉,所以:

答案为我工作,我只是通过该formset的形式需要循环,并设置初始数据为他们每个人:

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', ...}, {}... ]


Answer 6:

它在预先填充的情况下为我工作userrequest.userStackedInlineTabularInline

def save_formset(self, request, form, formset, change):
    for form in formset.forms:
        form.instance.user = request.user
    formset.save()


文章来源: Django: Admin inline forms initial data for every instance