Возможно изменение количества входов с формами Django?
Возможно ли иметь переменное число полей с использованием форм django?
Конкретным приложением является следующее:
Пользователь может загрузить столько изображений, сколько захочет, в форме загрузки изображения. Как только изображения загружены, они попадают на страницу, где они могут дать изображениям имя и описание. Количество снимков будет зависеть от того, сколько пользователей выбрало для загрузки.
Итак как мне получить django для создания формы с использованием переменной количества полей ввода (которая может быть передана в качестве аргумента при необходимости)?
edit: изменилось несколько вещей, так как была написана статья упомянутая в ответе Джеффа Бауэра.
А именно эта строка кода, которая, похоже, не работает:
# BAD CODE DO NOT USE!!!
return type('ContactForm', [forms.BaseForm], { 'base_fields': fields })
Итак, вот что я придумал...
Ответ, который я использовал:
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 не является частью django, но это бесплатно и очень полезно. проверьте это: django-tagging
Ответы
Ответ 1
Да, возможно динамически создавать формы в 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()
Для лучшей разработки этой техники см. статью Джеймса Беннетта: Итак, вы хотите динамическую форму?
http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/
Ответ 2
Если вы запустите
python manage.py shell
и введите:
from app.forms import PictureForm
p = PictureForm()
p.fields
type(p.fields)
вы увидите, что p.fields - это SortedDict. вам просто нужно вставить новое поле. Что-то вроде
p.fields.insert(len(p.fields)-2, 'fieldname', Field())
В этом случае он вставляет перед последним полем новое поле. Теперь вы должны адаптироваться к своему коду.
Другой альтернативой является создание цикла for/while в вашем шаблоне и выполнение формы в HTML, но django формирует рок по какой-то причине, правильно?
Ответ 3
Используйте либо несколько форм (django.forms.Form, не тег)
class Foo(forms.Form):
field = forms.Charfield()
forms = [Foo(prefix=i) for i in xrange(x)]
или добавьте несколько полей в форму динамически, используя 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()