预先填入内联FormSet? [英] Pre-populate an inline FormSet?

查看:83
本文介绍了预先填入内联FormSet?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为乐队参加考勤报名表。我的想法是让一部分表单输入表演或排练的事件信息。这是事件表的模型:

  class Event(models.Model):
event_id = models.AutoField( primary_key = True)
date = models.DateField()
event_type = models.ForeignKey(EventType)
description = models.TextField()
/ pre>

然后,我想有一个内联FormSet,将乐队成员链接到活动,并记录他们是否在场,缺席或被拒绝:

  class Attendance(models.Model):
attendance_id = models.AutoField(primary_key = True)
event_id = models .ForeignKey(Event)
member_id = models.ForeignKey(Member)
attendance_type = models.ForeignKey(AttendanceType)
comment = models.TextField(blank = True)

现在,我想做的是将所有当前成员的条目预先填充此内联FormSet,并将其默认为出席(约60名成员)。不幸的是,Django 在这种情况下不允许初始值。



任何建议?

解决方案

所以,你不是就像答案一样,部分是因为我还没有编写代码,部分是因为它的工作很多。



我发现你需要做什么当我遇到这个问题时,是:


  1. 花费大量时间阅读表单和模型表单代码,以获得感觉这一切如何工作(没有一些功能生活在formset类上,其中一些功能生活在工厂功能中,它们会吐出来)。您将在后面的步骤中需要这些知识。

  2. 编写自己的formset类,从 BaseInlineFormSet 子类中接受初始。这里真的很棘手的一点是,你必须覆盖 __ init __(),你必须确保它调用到 BaseFormSet .__ init __(),而不是使用直接父或祖父母 __ init __()(因为那些是$ $ c> BaseInlineFormSet 和 BaseModelFormSet ,它们都不能处理初始数据)。

  3. 编写自己的子类的适当的管理内联类(在我的情况下,它是 TabularInline ),并将其 get_formset 方法覆盖使用您的自定义表单类返回 inlineformset_factory()的结果。

  4. 在实际的 ModelAdmin 具有内联模型的子类,覆盖 add_view change_view ,并复制大部分代码,但是有一个很大的变化:构建您的formset将需要的初始数据,并将其传递给您的自定义表单集(将由您的 ModelAdmin get_formsets()方法)。

我与Brian和Joseph进行了几次生产性聊天,为未来的Django版本改进了这一点;目前,模型表单的工作方式只是使这种情况比通常值得的更麻烦,但是通过一些API清理,我认为这可以非常容易。


I'm working on an attendance entry form for a band. My idea is to have a section of the form to enter event information for a performance or rehearsal. Here's the model for the event table:

class Event(models.Model):
    event_id = models.AutoField(primary_key=True)
    date = models.DateField()
    event_type = models.ForeignKey(EventType)
    description = models.TextField()

Then I'd like to have an inline FormSet that links the band members to the event and records whether they were present, absent, or excused:

class Attendance(models.Model):
    attendance_id = models.AutoField(primary_key=True)
    event_id = models.ForeignKey(Event)
    member_id = models.ForeignKey(Member)
    attendance_type = models.ForeignKey(AttendanceType)
    comment = models.TextField(blank=True)

Now, what I'd like to do is to pre-populate this inline FormSet with entries for all the current members and default them to being present (around 60 members). Unfortunately, Django doesn't allow initial values in this case.

Any suggestions?

解决方案

So, you're not going to like the answer, partly because I'm not yet done writing the code and partly because it's a lot of work.

What you need to do, as I discovered when I ran into this myself, is:

  1. Spend a lot of time reading through the formset and model-formset code to get a feel for how it all works (not helped by the fact that some of the functionality lives on the formset classes, and some of it lives in factory functions which spit them out). You will need this knowledge in the later steps.
  2. Write your own formset class which subclasses from BaseInlineFormSet and accepts initial. The really tricky bit here is that you must override __init__(), and you must make sure that it calls up to BaseFormSet.__init__() rather than using the direct parent or grandparent __init__() (since those are BaseInlineFormSet and BaseModelFormSet, respectively, and neither of them can handle initial data).
  3. Write your own subclass of the appropriate admin inline class (in my case it was TabularInline) and override its get_formset method to return the result of inlineformset_factory() using your custom formset class.
  4. On the actual ModelAdmin subclass for the model with the inline, override add_view and change_view, and replicate most of the code, but with one big change: build the initial data your formset will need, and pass it to your custom formset (which will be returned by your ModelAdmin's get_formsets() method).

I've had a few productive chats with Brian and Joseph about improving this for future Django releases; at the moment, the way the model formsets work just make this more trouble than it's usually worth, but with a bit of API cleanup I think it could be made extremely easy.

这篇关于预先填入内联FormSet?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆