Django

Code

Ticket #9493: formset-unique.diff

File formset-unique.diff, 2.9 kB (added by Alex, 1 year ago)

needs test for unique_together and docs

  • a/django/forms/models.py

    old new  
    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            data = set() 
     398            for i in xrange(self._total_form_count): 
     399                form = self.forms[i] 
     400                if not hasattr(form, 'cleaned_data'): 
     401                    continue 
     402                if [True for field in unique_check if field in form.cleaned_data and form.cleaned_data[field] is not None]: 
     403                    if tuple([form.cleaned_data[field] for field in unique_check]) in data: 
     404                        bad_fields.add(unique_check) 
     405                    else: 
     406                        data.add(tuple([form.cleaned_data[field] for field in unique_check])) 
     407         
     408        if bad_fields: 
     409            errors = [] 
     410            for field in bad_fields: 
     411                if len(field) == 1: 
     412                    errors.append(_(u"You have entered duplicate data for %(field)s, all %(field)ss should be unique." % { 
     413                            'field': get_text_list(field, _("and")), 
     414                        })) 
     415                else: 
     416                    errors.append(_(u"You have entered duplicate data for %(fields)s, %(fields)ss should be unique together." % { 
     417                            'fields': get_text_list(field, _("and")), 
     418                        })) 
     419            raise ValidationError(errors) 
    380420 
    381421    def save_existing_objects(self, commit=True): 
    382422        self.changed_objects = [] 
  • a/tests/modeltests/model_formsets/models.py

    old new  
    777777>>> formset.get_queryset() 
    778778[<Player: Bobby>] 
    779779 
     780# Prevent duplicates from within the same formset 
     781>>> FormSet = modelformset_factory(Product, extra=2) 
     782>>> data = { 
     783...     'form-TOTAL_FORMS': 2, 
     784...     'form-INITIAL_FORMS': 0, 
     785...     'form-0-slug': 'red_car', 
     786...     'form-1-slug': 'red_car', 
     787... } 
     788>>> formset = FormSet(data) 
     789>>> formset.is_valid() 
     790False 
     791>>> formset._non_form_errors 
     792[u'You have entered duplicate data for slug, all slugs should be unique.'] 
    780793"""}