| 1 | @property
|
|---|
| 2 | def ordered_forms(self):
|
|---|
| 3 | '''
|
|---|
| 4 | see https://code.djangoproject.com/ticket/21592
|
|---|
| 5 |
|
|---|
| 6 | This overrides default behavior and makes this property
|
|---|
| 7 | available when is_valid() is False.
|
|---|
| 8 |
|
|---|
| 9 | Adjusted the property to fall back to form.data if
|
|---|
| 10 | form.cleaned_data isn't available
|
|---|
| 11 | '''
|
|---|
| 12 | """
|
|---|
| 13 | Returns a list of form in the order specified by the incoming data.
|
|---|
| 14 | Raises an AttributeError if ordering is not allowed.
|
|---|
| 15 | """
|
|---|
| 16 | if not self.can_order:
|
|---|
| 17 | raise AttributeError("'%s' object has no attribute 'ordered_forms'" % self.__class__.__name__)
|
|---|
| 18 | # Construct _ordering, which is a list of (form_index, order_field_value)
|
|---|
| 19 | # tuples. After constructing this list, we'll sort it by order_field_value
|
|---|
| 20 | # so we have a way to get to the form indexes in the order specified
|
|---|
| 21 | # by the form data.
|
|---|
| 22 | if not hasattr(self, '_ordering'):
|
|---|
| 23 | self._ordering = []
|
|---|
| 24 | for i in range(0, self.total_form_count()):
|
|---|
| 25 | form = self.forms[i]
|
|---|
| 26 | # if this is an extra form and hasn't changed, don't consider it
|
|---|
| 27 | if i >= self.initial_form_count() and not form.has_changed():
|
|---|
| 28 | continue
|
|---|
| 29 | # don't add data marked for deletion to self.ordered_data
|
|---|
| 30 | if self.can_delete and self._should_delete_form(form):
|
|---|
| 31 | continue
|
|---|
| 32 |
|
|---|
| 33 | key = ORDERING_FIELD_NAME
|
|---|
| 34 | try:
|
|---|
| 35 | data = form.cleaned_data
|
|---|
| 36 | except AttributeError:
|
|---|
| 37 | data = form.data
|
|---|
| 38 | key = "%s-%s" % (form.prefix, key)
|
|---|
| 39 |
|
|---|
| 40 | self._ordering.append((i, data[key]))
|
|---|
| 41 | # After we're done populating self._ordering, sort it.
|
|---|
| 42 | # A sort function to order things numerically ascending, but
|
|---|
| 43 | # None should be sorted below anything else. Allowing None as
|
|---|
| 44 | # a comparison value makes it so we can leave ordering fields
|
|---|
| 45 | # blank.
|
|---|
| 46 | def compare_ordering_key(k):
|
|---|
| 47 | if k[1] is None:
|
|---|
| 48 | return (1, 0) # +infinity, larger than any number
|
|---|
| 49 | return (0, k[1])
|
|---|
| 50 | self._ordering.sort(key=compare_ordering_key)
|
|---|
| 51 | # Return a list of form.cleaned_data dicts in the order specified by
|
|---|
| 52 | # the form data.
|
|---|
| 53 | return [self.forms[i[0]] for i in self._ordering]
|
|---|