【问题标题】:How to pass in a parameter to the form within the formset?如何将参数传递给表单集中的表单?
【发布时间】:2012-08-12 01:55:20
【问题描述】:

我想创建一个表单集,其中每个表单都有一个指向一组销售项目的下拉列表。

型号:

class SalesItem(models.Model):        
    item_description    = models.CharField(max_length=40)
    company             = models.ForeignKey(Company)

在这里我创建了一个带有下拉列表的表单,希望将公司作为下拉列表的来源。坚持这个想法,因为我认为这在我的场景中是不可能的。

表格:

class SalesItemFSForm(Form):        
    sales_item      =   forms.ModelChoiceField(required=False, queryset = '')

    def __init__(self, company, *args, **kwargs):
        super(SalesItemFSForm, self).__init__(*args, **kwargs)
        self.fields.sales_item.queryset = company.salesitem_set.all()

现在在我看来,我想用这个表单创建一个表单集:

formset_type = formset_factory(SalesItemFSForm, extra=0)

问题马上就清楚了,因为我似乎无法通过公司来确定下拉列表的来源。

我该怎么做?

非常感谢,

更新:

看来Jingo 破解了它。 :)

ModelForm 比 Form 更有效。最重要的是,我必须将fields = {} 添加到SalesItemFSForm,以确保SalesItem 的字段没有显示在模板中。因为我们感兴趣的只是我们的下拉列表 (SalesItem)。

到目前为止一切顺利。但现在我看到显示的下拉菜单与销售项目一样多。它不应该显示任何内容,除非用户按下 jquery 按钮。

我认为这是问题所在,我们不应该传入

formset_type = modelformset_factory(SalesItem, form=SalesItemFSForm, extra=0)

因为我们的表单不需要任何 SalesItem 实例。我们需要一个虚拟模型。

这就是我最初尝试使用经典 Formset 而不是 ModelFormset 来解决它的原因。所以它有点一半。 :)

更新 2:

Jingo,说得好。实际上,我正在考虑自定义保存,在这里我只看到用户通过 jQuery 添加了多少表单集并将其保存在视图中。从字面上看,SalesItem 是一个多对多字段。但是标准的 M2m 小部件是可怕的。因此,我想用表单集替换它,其中每个 salesItem 都是一个下拉列表。然后,用户可以向页面添加尽可能多的下拉列表(formset 中的表单)并提交它们。然后我会在视图中添加关系。

class DealType(models.Model):    
    deal_name           = models.CharField(_(u"Deal Name"), max_length=40)
    sales_item          = models.ManyToManyField(SalesItem)    
    price               = models.DecimalField(decimal_places=2, max_digits=12)

希望这能说明问题。也许有一种更简单的方法可以做到这一点。 :)

顺便说一句,我还发现了这个优秀的 jquery snippet code how to add/remove forms to/from a formset。

更新 3:

确实,当像这样实例化对象时,我们只会在表单集中获得一个表单,并且可以通过 jquery 添加更多表单。完美的!!除非有更简单的方法来实现这一点。 :)

salesitem_formsets = formset_type(queryset=SalesItem.objects.filter(pk=1))

然而,这又会在 request.POST 中追捕你,因为你不能只是这样做:

salesitem_formsets = formset_type(request.POST)

它仍然需要设置查询集。棘手的情况...

【问题讨论】:

  • @supervacuo 根本问题是相同的,但使用不同的小部件。所以你试图用内联表单集来解决它,很有趣,但你似乎也没有解决这个问题,对吗?
  • 当您实例化表单时(即:formset_type()),您可以在一个空的查询集中传递 a,例如(通常 Django 使用“.all()”)。比如:formset_type(queryset=SalesItem.objects.none())。看到这里docs.djangoproject.com/en/dev/topics/forms/modelforms/…,等等,不,仍然不对:/
  • 所以,在我看来,猫会咬自己的尾巴一点点。真的是必须用于表单集表单的 SalesItem 吗??
  • 嘿Kave,我在工作atm,我可以尝试在没人的时候加入聊天:P,情况真的很棘手,也许我们必须从头开始解决问题,我得到了那种感觉:P

标签: django formset


【解决方案1】:

我希望我能正确理解您想要实现的目标。那么也许你可以像这样使用 ModelForm 及其可用的实例:

class SalesItemFSForm(forms.ModelForm):
    class Meta:
        model = SalesItem

    def __init__(self, *args, **kwargs):
        super(SalesItemFSForm, self).__init__(*args, **kwargs)
        self.sale_items = self.instance.company.salesitem_set.all()
        self.fields['sales_item'] = forms.ModelChoiceField(queryset=self.sale_items)

虽然这未经测试,只是一个想法。我希望这会导致正确的方向,但是如果完全错误,请告诉我,我将删除我的答案,以免其他人感到困惑:)。

【讨论】:

  • 有趣。我可以试试这个,但从逻辑上讲它可能有问题,因为 salesitem.company.sales_item_set.all() 将与 SalesItem.objects.all() 相同,不是吗?这是一个问题,因为我想为给定的公司过滤它。 :) 不确定...需要测试。不过还是谢谢
  • 至少在 shell 中这两个查询集是不一样的。你已经可以测试了吗?我真的对调查结果很感兴趣 :),因为我在尝试对小型调查系统进行编程时尝试解决一些类似的问题...
  • 当然没问题。我已经尝试过了,在实例化它时得到了这个错误消息:salesitem_formsets = formset_type(data) 错误消息是:self.sale_items = self.instance.company.salesitem_set.all() 和 raise self.field.rel.to.DoesNotExist。查看完整回溯:heypasteit.com/clip/0FWR
  • 嗯好的,您可以尝试使用 modelformset_factory 并将模型作为第一个参数传递。像这样 form = modelformset_factory(SalesItem, extra=0, form=SalesItemFSForm)
  • 你是个天才。它几乎完全工作。请参阅更新的问题。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2018-02-26
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
相关资源
最近更新 更多