Django formset中每个表单的不同初始数据

cer*_*ial 30 django django-forms

是否可以为每行预填充具有不同数据的formset?我想将一些信息放在前一个视图的隐藏字段中.

根据文档,您只能全面设置.

Ali*_*air 56

如果你犯了和我一样的错误,你就会误解文档.

当我第一次看到这个例子时......

formset = ArticleFormSet(initial=[
 {'title': 'Django is now open source',
  'pub_date': datetime.date.today(),}
])
Run Code Online (Sandbox Code Playgroud)

我假设每个表单都基于字典给出了相同的初始数据集.

但是,如果你仔细观察,你会发现formset实际上是传递了一个字典列表.

为了在formset中为每个表单设置不同的初始值,您只需要传递包含不同数据的字典列表.

Formset = formset_factory(SomeForm, extra=len(some_objects)
some_formset = FormSet(initial=[{'id': x.id} for x in some_objects])
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是执行此操作的最简单方法,也是默认的Django方法,并确定了OP的错误概念.应该是最好的答案. (3认同)
  • @Alistair,您在这里犯了一个小错误,它是`{'id':x.id}`而不是`{'id':'x.id'}` (2认同)

小智 11

你需要使用这篇文章中描述的技术,以便能够传入参数.感谢该作者的优秀帖子.您可以在以下几个部分实现此目

表单意识到它将获取其他参数

链接问题的示例:

def __init__(self, *args, **kwargs):
    someeobject = kwargs.pop('someobject')
    super(ServiceForm, self).__init__(*args, **kwargs)
    self.fields["somefield"].queryset = ServiceOption.objects.filter(
                                                           somem2mrel=someobject)
Run Code Online (Sandbox Code Playgroud)

或者你可以用后面的代码替换

    self.fields["somefield"].initial = someobject
Run Code Online (Sandbox Code Playgroud)

直接,它的工作原理.

一个curried表单初始化设置:

formset = formset_factory(Someform, extra=3)
formset.form = staticmethod(curry(someform, somem2mrel=someobject))
Run Code Online (Sandbox Code Playgroud)

这可以让您传递自定义表单参数.现在你需要的是:

用于获取不同初始参数的生成器

我正在使用这个:

def ItemGenerator(Item):
    i = 0
    while i < len(Item):
        yield Item[i]
        i += 1
Run Code Online (Sandbox Code Playgroud)

现在,我可以这样做:

iterdefs = ItemGenerator(ListofItems) # pass the different parameters 
                                      # as an object here
formset.form = staticmethod(curry(someform, somem2mrel=iterdefs.next()))
Run Code Online (Sandbox Code Playgroud)

嘿presto.该form方法的每个评估都在传递迭代参数的部分中进行评估.我们可以迭代我们喜欢的东西,所以我使用这个事实迭代一组对象并将每个对象的值作为不同的初始参数传递.


die*_*us9 2

我遇到了这个问题,我做了一个新的小部件:

from django.forms.widgets import Select
from django.utils.safestring import mark_safe
class PrepolutatedSelect(Select):
    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = ''
        if value == '':
            value = int(name.split('-')[1])+1
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<select%s>' % flatatt(final_attrs)]
        options = self.render_options(choices, [value])
        if options:
            output.append(options)
        output.append('</select>')
        return mark_safe(u'\n'.join(output))
Run Code Online (Sandbox Code Playgroud)

也许这对你也有用。