python 可以使用 Django 表单进行可变数量的输入吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/411761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:03:12  来源:igfitidea点击:

Variable number of inputs with Django forms possible?

pythondjangodjango-forms

提问by Jiaaro

Is it possible to have a variable number of fields using django forms?

是否可以使用 django 表单拥有可变数量的字段?

The specific application is this:

具体应用是这样的:

A user can upload as many pictures as they want on the image upload form. Once the pictures are uploaded they are taken to a page where they can give the pictures a name and description. The number of pictures will depend on how many the user has chosen to upload.

用户可以在图片上传表单上上传任意数量的图片。图片上传后,它们会被带到一个页面,在那里他们可以为图片命名和描述。图片的数量将取决于用户选择上传的数量。

So how do I get django to generate a form using a variable number of input fields(which could be passed as an argument if necessary)?

那么如何让 django 使用可变数量的输入字段(如果需要,可以作为参数传递)来生成表单

edit:a few things have changed since the article mentioned in jeff bauer's answerwas written.

编辑:自从jeff bauer 的回答中提到文章撰写以来,一些事情发生了变化。

Namely this line of code which doesn't seem to work:

即这行代码似乎不起作用:

# BAD CODE DO NOT USE!!!
return type('ContactForm', [forms.BaseForm], { 'base_fields': fields })

So here is what I came up with...

所以这就是我想出的……

The Answer I used:

我使用的答案:


from tagging.forms import TagField
from django import forms

def make_tagPhotos_form(photoIdList):
    "Expects a LIST of photo objects (ie. photo_sharing.models.photo)"

    fields = {}

    for id in photoIdList:
        id = str(id)

        fields[id+'_name'] = forms.CharField()
        fields[id+'_tags'] = TagField()
        fields[id+'_description'] = forms.CharField(widget=forms.Textarea)

    return type('tagPhotos', (forms.BaseForm,), { 'base_fields': fields })

note tagging is not part of django, but it is free and very useful. check it out: django-tagging

注释标记不是 django 的一部分,但它是免费的并且非常有用。检查一下:django-标记

采纳答案by Jeff Bauer

Yes, it's possible to create forms dynamically in Django. You can even mix and match dynamic fields with normal fields.

是的,可以在 Django 中动态创建表单。您甚至可以将动态字段与普通字段混合搭配。

class EligibilityForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(EligibilityForm, self).__init__(*args, **kwargs)
        # dynamic fields here ...
        self.fields['plan_id'] = CharField()
    # normal fields here ...
    date_requested = DateField()

For a better elaboration of this technique, see James Bennett's article: So you want a dynamic form?

为了更好地阐述这项技术,请参阅 James Bennett 的文章:So you want a dynamic form?

http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/

http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/

回答by Alcides

If you run

如果你跑

python manage.py shell

and type:

并输入:

from app.forms import PictureForm
p = PictureForm()
p.fields
type(p.fields)

you'll see that p.fields is a SortedDict. you just have to insert a new field. Something like

你会看到 p.fields 是一个 SortedDict。你只需要插入一个新字段。就像是

p.fields.insert(len(p.fields)-2, 'fieldname', Field())

In this case it would insert before the last field, a new field. You should now adapt to your code.

在这种情况下,它将在最后一个字段之前插入一个新字段。您现在应该适应您的代码。

Other alternative is to make a for/while loop in your template and do the form in HTML, but django forms rock for some reason, right?

另一种选择是在你的模板中创建一个 for/while 循环并在 HTML 中执行表单,但是 django 表单由于某种原因而摇摆不定,对吗?

回答by user51463

Use either multiple forms (django.forms.Form not the tag)

使用多种形式(django.forms.Form 不是标签)

class Foo(forms.Form):
    field = forms.Charfield()

forms = [Foo(prefix=i) for i in xrange(x)]

or add multiple fields to the form dynamically using self.fields.

或者使用 self.fields 动态地向表单添加多个字段。

class Bar(forms.Form):
    def __init__(self, fields, *args, **kwargs):
        super(Bar, self).__init__(*args, **kwargs)
        for i in xrange(fields):
            self.fields['my_field_%i' % i] = forms.Charfield()