Ticket #8882: formset-unique.diff

File formset-unique.diff, 2.6 KB (added by Alex, 6 years ago)
  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index 0c98f52..7cbf3ab 100644
    a b class BaseModelFormSet(BaseFormSet): 
    377377                    form.save_m2m()
    378378            self.save_m2m = save_m2m
    379379        return self.save_existing_objects(commit) + self.save_new_objects(commit)
     380   
     381    def clean(self):
     382        self.validate_unique()
     383   
     384    def validate_unique(self):
     385        from django.db.models.fields import FieldDoesNotExist
     386        unique_checks = []
     387        for name, field in self.forms[0].fields.iteritems():
     388            try:
     389                f = self.forms[0].instance._meta.get_field_by_name(name)[0]
     390            except FieldDoesNotExist:
     391                continue
     392            if f.unique:
     393                unique_checks.append((name,))
     394       
     395        bad_fields = set()
     396        for unique_check in unique_checks:
     397            if len(unique_check) == 1:
     398                field = unique_check[0]
     399                data = set()
     400                for i in xrange(self._total_form_count):
     401                    form = self.forms[i]
     402                    if hasattr(form, 'cleaned_data') and field in form.cleaned_data and form.cleaned_data[field] is not None:
     403                        if form.cleaned_data[field] in data:
     404                            bad_fields.add(unique_check)
     405                        else:
     406                            data.add(form.cleaned_data[field])
     407       
     408        if bad_fields:
     409            errors = []
     410            for field in bad_fields:
     411                errors.append(_(u"You have entered duplicate data for %(field)s, all %(field)ss should be unique" % {
     412                        'field': get_text_list(field, _(u'and'))
     413                    }))
     414            raise ValidationError(errors)
    380415
    381416    def save_existing_objects(self, commit=True):
    382417        self.changed_objects = []
  • tests/modeltests/model_formsets/models.py

    diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py
    index 215f35b..94d4d27 100644
    a b True 
    727727>>> formset.get_queryset()
    728728[<Player: Bobby>]
    729729
     730# Prevent duplicates from within the same formset
     731>>> FormSet = modelformset_factory(Product, extra=2)
     732>>> data = {
     733...     'form-TOTAL_FORMS': 2,
     734...     'form-INITIAL_FORMS': 0,
     735...     'form-0-slug': 'red_car',
     736...     'form-1-slug': 'red_car',
     737... }
     738>>> formset = FormSet(data)
     739>>> formset.is_valid()
     740False
     741>>> formset._non_form_errors
     742[u'You have entered duplicate data for slug, all slugs should be unique']
    730743"""}
Back to Top