160 | | if not self.is_valid() or not self.can_delete: |
161 | | raise AttributeError("'%s' object has no attribute 'deleted_forms'" % self.__class__.__name__) |
162 | | # construct _deleted_form_indexes which is just a list of form indexes |
163 | | # that have had their deletion widget set to True |
164 | | if not hasattr(self, '_deleted_form_indexes'): |
165 | | self._deleted_form_indexes = [] |
166 | | for i in range(0, self.total_form_count()): |
167 | | form = self.forms[i] |
168 | | # if this is an extra form and hasn't changed, don't consider it |
169 | | if i >= self.initial_form_count() and not form.has_changed(): |
170 | | continue |
171 | | if self._should_delete_form(form): |
172 | | self._deleted_form_indexes.append(i) |
173 | | return [self.forms[i] for i in self._deleted_form_indexes] |
| 169 | if self._errors is None: |
| 170 | self.full_clean() |
| 171 | return self._deleted_forms |
181 | | if not self.is_valid() or not self.can_order: |
182 | | raise AttributeError("'%s' object has no attribute 'ordered_forms'" % self.__class__.__name__) |
183 | | # Construct _ordering, which is a list of (form_index, order_field_value) |
184 | | # tuples. After constructing this list, we'll sort it by order_field_value |
185 | | # so we have a way to get to the form indexes in the order specified |
186 | | # by the form data. |
187 | | if not hasattr(self, '_ordering'): |
188 | | self._ordering = [] |
189 | | for i in range(0, self.total_form_count()): |
190 | | form = self.forms[i] |
191 | | # if this is an extra form and hasn't changed, don't consider it |
192 | | if i >= self.initial_form_count() and not form.has_changed(): |
193 | | continue |
194 | | # don't add data marked for deletion to self.ordered_data |
195 | | if self.can_delete and self._should_delete_form(form): |
196 | | continue |
197 | | self._ordering.append((i, form.cleaned_data[ORDERING_FIELD_NAME])) |
198 | | # After we're done populating self._ordering, sort it. |
199 | | # A sort function to order things numerically ascending, but |
200 | | # None should be sorted below anything else. Allowing None as |
201 | | # a comparison value makes it so we can leave ordering fields |
202 | | # blamk. |
203 | | def compare_ordering_values(x, y): |
204 | | if x[1] is None: |
205 | | return 1 |
206 | | if y[1] is None: |
207 | | return -1 |
208 | | return x[1] - y[1] |
209 | | self._ordering.sort(compare_ordering_values) |
210 | | # Return a list of form.cleaned_data dicts in the order spcified by |
211 | | # the form data. |
212 | | return [self.forms[i[0]] for i in self._ordering] |
| 179 | if self._errors is None: |
| 180 | self.full_clean() |
| 181 | return self._ordered_forms |
| 244 | # Consider only forms that are initial or changed. |
| 245 | if i < self.initial_form_count() or form.has_changed(): |
| 246 | if self.can_delete and self._should_delete_form(form): |
| 247 | # Add index of form that should be deleted. |
| 248 | deleted_form_indexes.append(i) |
| 249 | else: |
| 250 | if form.is_valid(): |
| 251 | if self.can_order: |
| 252 | # Add index and order field value of valid form. |
| 253 | valid_form_indexes.append((i, form.cleaned_data[ORDERING_FIELD_NAME])) |
| 254 | else: |
| 255 | # Add index of valid form. |
| 256 | valid_form_indexes.append(i) |
| 257 | else: |
| 258 | # Mark formset as not valid but do not stop to make |
| 259 | # sure validation gets triggered for every form. |
| 260 | self._is_valid = False |
| 266 | self._is_valid = False |
| 267 | # If formset is valid, populates self._valid_forms, |
| 268 | # self._ordered_forms (if can_order is True) and self._deleted_forms |
| 269 | # (if can_delete is True). |
| 270 | if self._is_valid: |
| 271 | if self.can_order: |
| 272 | # A sort function to order things numerically ascending, but |
| 273 | # None should be sorted below anything else. Allowing None as |
| 274 | # a comparison value makes it so we can leave ordering fields |
| 275 | # blank. |
| 276 | def compare_ordering_values(x, y): |
| 277 | if x[1] is None: |
| 278 | return 1 |
| 279 | if y[1] is None: |
| 280 | return -1 |
| 281 | return x[1] - y[1] |
| 282 | valid_form_indexes.sort(compare_ordering_values) |
| 283 | self._valid_forms = [self.forms[i[0]] for i in valid_form_indexes] |
| 284 | self._ordered_forms = self._valid_forms |
| 285 | else: |
| 286 | self._valid_forms = [self.forms[i] for i in valid_form_indexes] |
| 287 | if self.can_delete: |
| 288 | self._deleted_forms = [self.forms[i] for i in deleted_form_indexes] |