Construct and return a model instance from the bound ``form``'s ``cleaned_data``, but do not save the returned instance to the database.
(form, instance, fields=None, exclude=None)
| 48 | |
| 49 | |
| 50 | def construct_instance(form, instance, fields=None, exclude=None): |
| 51 | """ |
| 52 | Construct and return a model instance from the bound ``form``'s |
| 53 | ``cleaned_data``, but do not save the returned instance to the database. |
| 54 | """ |
| 55 | from django.db import models |
| 56 | |
| 57 | opts = instance._meta |
| 58 | |
| 59 | cleaned_data = form.cleaned_data |
| 60 | file_field_list = [] |
| 61 | for f in opts.fields: |
| 62 | if ( |
| 63 | not f.editable |
| 64 | or isinstance(f, models.AutoField) |
| 65 | or f.name not in cleaned_data |
| 66 | ): |
| 67 | continue |
| 68 | if fields is not None and f.name not in fields: |
| 69 | continue |
| 70 | if exclude and f.name in exclude: |
| 71 | continue |
| 72 | # Leave defaults for fields that aren't in POST data, except for |
| 73 | # checkbox inputs because they don't appear in POST data if not |
| 74 | # checked. |
| 75 | if ( |
| 76 | f.has_default() |
| 77 | and form[f.name].field.widget.value_omitted_from_data( |
| 78 | form.data, form.files, form.add_prefix(f.name) |
| 79 | ) |
| 80 | and cleaned_data.get(f.name) in form[f.name].field.empty_values |
| 81 | ): |
| 82 | continue |
| 83 | # Defer saving file-type fields until after the other fields, so a |
| 84 | # callable upload_to can use the values from other fields. |
| 85 | if isinstance(f, models.FileField): |
| 86 | file_field_list.append(f) |
| 87 | else: |
| 88 | f.save_form_data(instance, cleaned_data[f.name]) |
| 89 | |
| 90 | for f in file_field_list: |
| 91 | f.save_form_data(instance, cleaned_data[f.name]) |
| 92 | |
| 93 | return instance |
| 94 | |
| 95 | |
| 96 | # ModelForms ################################################################# |