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

时间:2012-09-12 09:22:53

标签: django django-admin

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

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

我有一个名为“Environments”的模型和一个名为“Servers”的模型,服务器和环境之间存在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个服务器表单实例。什么是最好的方法?

谢谢!

6 个答案:

答案 0 :(得分:9)

以下是我的实施,thanks to Steven for the idea

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

答案 1 :(得分:6)

不确定为什么要这样做,但也许你可以创建一个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

答案 2 :(得分:4)

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

我最后做的是覆盖Environment类save_model方法,而不是使用管理表单。

我会更好地解释一下:

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

答案 3 :(得分:3)

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

我只是阅读了文档,看起来你可以define your own formset inside your inlineadmin,然后如上所述,使用列表中的数据预填充formset。我认为您可以通过将预填充代码放在班级的 init 方法中来实现这一目标。

我知道这不是一个非常精细的解释,但我发现这个问题很有意思,并查阅了文档,并想到也许我可以指出你正确的方向,然后尝试下一步。

答案 4 :(得分:2)

嗯,我想对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', ...}, {}... ]

答案 5 :(得分:0)

如果user request.user StackedInline TabularInlinedef save_formset(self, request, form, formset, change): for form in formset.forms: form.instance.user = request.user formset.save() 预填充function viewAttendanceSheet() { var date = $("#datepicker").val(); $.ajax({ type: 'GET', url: "attendanceList", dataType: "json", data: { "date": date }, success: function(data, status) { alert(status); alert(JSON.stringify(data.length)); var res = String(JSON.stringify(data)).split(","); if (data.length == 0) { newRowContent = ("<tr>NOTHING TO DISPALY...</tr>"); $("#ajaxViewAttendanceSheet").append(newRowContent); } else { $("#attendanceViewTableHead").css("display", "block"); $.each(data, function(key, value) { if (value.status == "Absent") { newRowContent = ("<tr><td>" + value.studentName + "</td><td style=color:red;>" + value.status + "**</td></tr>"); } else { newRowContent = ("<tr><td>" + value.studentName + "</td><td style=color:green;>" + value.status + "</td></tr>"); } $("#ajaxViewAttendanceSheet").append(newRowContent); }); } } }); } ,则对我有用。

Update table set column1=column1-{'523_6'},cloumn1=column1+{'523_4'} where id='Your Id'