1

I have problem with my app. After upgrading Django to latest version - 1.11.4, I am getting the same error for three of my tests.

AssertionError: False is not true : The formset 'formset' in context 0 does not contain the non-form error 'Musi być podana co najmniej jedna stawka' (actual errors: ['Proszę wysłać 1 lub więcej formularzy.'])

I know that errors are in polish language but the fact is one, It was working with Django 1.9 and Django 1.10 but it is not with Django 1.11.

Could somebody tell me what was changed in Django 1.11 with forests?? I have read a lot of stuff about it and I have tried almost everything but old version is not working.

Maybe this formset doesn't see my error message and I have to make errors in another way after upgrading?

class BaseTaxRateInlineFormSet(UniqueFieldsFormSetMixin,
                               NotEmptyInlineFormSetMixin,
                               BaseInlineFormSet):
    _unique_fields = ('valid_from',)
    msg_at_least_one_required = __('Musi być podana co najmniej jedna stawka')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.queryset = self.queryset.order_by('valid_from')

superclasses:

class NotEmptyInlineFormSetMixin(object):
    """
    Prevents from deleting last not empty row (when other are empty)
    """
    msg_at_least_one_required = __(
        'Co najmniej jeden wiersz musi być wypełniony'
    )
    code_at_least_one_required = 'at_least_one_required'

    def _form_is_empty(self, form):
        return not len(list(filter(None, form.cleaned_data.values())))

    def clean(self):
        super().clean()

        if any(self.errors):
            return

        forms_to_delete = 0
        forms_empty = 0
        for form in self.forms:
            if self._should_delete_form(form):
                forms_to_delete += 1
            elif self._form_is_empty(form):
                forms_empty += 1

        if forms_to_delete + forms_empty == self.total_form_count():
            raise ValidationError(
                self.msg_at_least_one_required,
                code=self.code_at_least_one_required
            )


class UniqueFieldsFormSetMixin(object):
    """
    Checks if fields (_unique_fields) have unique values in all forms
    """
    _unique_fields = []
    msg_field_not_unique = __('Wartość nie może się powtarzać')
    code_field_not_unique = 'field_not_unique'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if 'unique_fields' in kwargs:
            self._unique_fields = kwargs.pop('unique_fields', [])

    def clean(self):
        super().clean()

        if self._unique_fields:
            values = {field: set() for field in self._unique_fields}
            for form in self.forms:
                for field in self._unique_fields:
                    val = form.cleaned_data.get(field)
                    if val:
                        if val in values[field]:
                            form.add_error(
                                field,
                                ValidationError(
                                    self.msg_field_not_unique,
                                    code=self.code_field_not_unique
                                )
                            )
                        values[field].add(val)

and test:

def test_update_removing_last_row(self):
    data = {
        # One row for existing rates and one empty.
        self.FORMSET_PREFIX + '-TOTAL_FORMS': 2,
        self.FORMSET_PREFIX + '-INITIAL_FORMS': 1,
        self.FORMSET_PREFIX + '-MAX_NUM_FORMS': 100
    }
    # First row exists
    data = self._load_formset_data(
        data, dict(
            self.rate_data_1, DELETE='on',
            **{'id': self.rate_pk_1, self.related_field: self.instance_pk}
        ), name=self.instance_name
    )

    self.client.force_login(self.superuser)
    response = self.client.post(self.url_update, data=data)
    # Can't remove last row
    self.assertEqual(response.status_code, 200)
    self.assertFormsetError(
        response, 'formset', None, None,
        self.base_formset_class.msg_at_least_one_required
    )
4

1 回答 1

0

问题在于两行 Django formset。

if not form.has_changed() and i >= self.initial_form_count():
    empty_forms_count += 1

在这种情况下,Django 知道我的哪些表单是空的并且没有更改。

如何更改我的测试或表单集的实现以在我的测试机中没有失败?

于 2017-08-16T05:42:00.800 回答