| 584 | FileField, ImageField and forms |
| 585 | =============================== |
| 586 | |
| 587 | Where most, if not all, model fields only require a simple addition in the |
| 588 | form of ``{{ form.fieldname }}`` to a template, the situation is a bit |
| 589 | different for the FileField and ImageField fields. |
| 590 | |
| 591 | Say that in the model definition there is a declaration for:: |
| 592 | |
| 593 | file = model.FileField('/path/to/upload/location') |
| 594 | |
| 595 | Normally this would be used in a template form like the following:: |
| 596 | |
| 597 | <p><label for="file">File:</label> {{ form.file }}</p> |
| 598 | |
| 599 | The first thing that is noticeable when the page is opened in a browser is |
| 600 | that there is no typical text field with a browse button, as would be |
| 601 | expected. |
| 602 | |
| 603 | To get this behaviour a little change to the template is needed to get the |
| 604 | following:: |
| 605 | |
| 606 | <p><label for="file">File:</label> {{ form.file }}{{ form.file_file }}</p> |
| 607 | |
| 608 | If you would reload the page it should now show a file upload text field |
| 609 | complete with a browse button. |
| 610 | |
| 611 | The HTML standard specifies the ``enctype`` attribute to the ``form`` element |
| 612 | in order to select the content type used in submitting. The default is |
| 613 | ``application/x-www-form-urlencoded``, the format that uses ampersands in the |
| 614 | URL to separate key-value pairs as well as some other encoding tricks. This |
| 615 | the wrong encoding type to use when working with forms that will use file |
| 616 | uploads. The ``form`` element must get an ``enctype`` attribute with its value |
| 617 | set to ``multipart/form-data``. |
| 618 | |
| 619 | Also make sure to use ``form.file_file`` with validation and not |
| 620 | ``form.file``. |
| 621 | |
| 622 | In the view make sure that the ``update(request.FILES)`` method is called |
| 623 | after the object has been created with the ``request.POST.copy()`` call, as |
| 624 | such:: |
| 625 | |
| 626 | new_data = request.POST.copy() |
| 627 | new_data.update(request.FILES) |
| 628 | |