diff --git a/AUTHORS b/AUTHORS index 18035835b2cdd..9e6ece6eb2890 100644 --- a/AUTHORS +++ b/AUTHORS @@ -195,6 +195,7 @@ answer newbie questions, and generally made Django that much better: Martin Maney masonsimon+django@gmail.com Manuzhai + Petr Marhoun Petar Marić Nuno Mariz Marijn Vriens diff --git a/django/newforms/forms.py b/django/newforms/forms.py index ab8729be657f5..2b1caddedab2b 100644 --- a/django/newforms/forms.py +++ b/django/newforms/forms.py @@ -212,6 +212,16 @@ def clean(self): """ return self.cleaned_data + def is_multipart(self): + """ + Returns True if the form needs to be multipart-encrypted, i.e. it has + FileInput. Otherwise, False. + """ + for field in self.fields.values(): + if field.widget.needs_multipart_form: + return True + return False + class Form(BaseForm): "A collection of Fields, plus their associated data." # This is a separate class from BaseForm in order to abstract the way diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py index f98512438900b..0e7752499e739 100644 --- a/django/newforms/widgets.py +++ b/django/newforms/widgets.py @@ -24,6 +24,7 @@ class Widget(object): is_hidden = False # Determines whether this corresponds to an . + needs_multipart_form = False # Determines does this widget need multipart-encrypted form def __init__(self, attrs=None): if attrs is not None: @@ -120,6 +121,7 @@ def value_from_datadict(self, data, files, name): class FileInput(Input): input_type = 'file' + needs_multipart_form = True def render(self, name, value, attrs=None): return super(FileInput, self).render(name, None, attrs=attrs) diff --git a/docs/newforms.txt b/docs/newforms.txt index e9e98944a0442..ba0247314b55d 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -776,6 +776,27 @@ form data *and* file data:: # Unbound form with a image field >>> f = ContactFormWithMugshot() +Testing for multipart forms +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you're writing some reusable views or templates, you may not know ahead of +time whether your form is a multipart form or not. The ``is_multipart()`` +method tells you if the form requires multipart encoding for submission:: + + >>> f = ContactFormWithMugshot() + >>> f.is_multipart() + True + +In a template, this sort of code could be useful:: + + {% if form.is_multipart %} +
+ {% else %} + + {% endif %} + {% form %} +
+ Subclassing forms ----------------- diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index fef8361a14132..b85897897f060 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3856,6 +3856,25 @@
This field is required.

Comment:

+################################# +# Test multipart-encoded form # +################################# + +>>> class FormWithoutFile(Form): +... username = CharField() +>>> class FormWithFile(Form): +... username = CharField() +... file = FileField() +>>> class FormWithImage(Form): +... image = ImageField() + +>>> FormWithoutFile().is_multipart() +False +>>> FormWithFile().is_multipart() +True +>>> FormWithImage().is_multipart() +True + """ __test__ = {