Ticket #8209: django-r8769-8209.2.diff

File django-r8769-8209.2.diff, 5.7 KB (added by Alex, 7 years ago)

Fixed merge errors with latest trunk

  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index 6acd32c..112a2ff 100644
    a b class BaseModelForm(BaseForm): 
    202202            object_data.update(initial)
    203203        super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data,
    204204                                            error_class, label_suffix, empty_permitted)
     205    def clean(self):
     206        self.validate_unique()
     207        return self.cleaned_data
     208   
     209    def validate_unique(self):
     210        from django.db.models.fields import FieldDoesNotExist
     211        unique_checks = self.instance._meta.unique_together[:]
     212        form_errors = []
     213        for name, field in self.fields.items():
     214            try:
     215                if name in self.cleaned_data and self.instance._meta.get_field_by_name(name)[0].unique and not self.instance._meta.get_field_by_name(name)[0].primary_key:
     216                    unique_checks.append((name,))
     217            except FieldDoesNotExist:
     218                # This is an extra field that's not on the model, ignore it
     219                pass
     220        for unique_check in [check for check in unique_checks if not any([x in self._errors for x in check])]:
     221            kwargs = dict([(field_name, self.cleaned_data[field_name]) for field_name in unique_check])
     222            qs = self.instance.__class__._default_manager.filter(**kwargs)
     223            if self.instance.pk is not None:
     224                qs = qs.exclude(pk=self.instance.pk)
     225            if qs.count() != 0:
     226                model_name = self.instance._meta.verbose_name.title()
     227                if len(unique_check) == 1:
     228                    field_name = unique_check[0]
     229                    field_label = self.fields[field_name].label
     230                    self._errors[field_name] = ErrorList(["%s with this %s already exists." % (model_name, field_label)])
     231                else:
     232                    field_labels = [self.fields[field_name].label for field_name in unique_check]
     233                    form_errors.append("%s with this %s already exists." % (model_name, ' and '.join(field_labels)))
     234                for field_name in unique_check:
     235                    del self.cleaned_data[field_name]
     236        if form_errors:
     237            raise ValidationError(form_errors)
    205238
    206239    def save(self, commit=True):
    207240        """
  • docs/topics/forms/modelforms.txt

    diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
    index d161b3f..163c428 100644
    a b parameter when declaring the form field:: 
    338338   ...     class Meta:
    339339   ...         model = Article
    340340
     341Overriding the clean() method
     342-----------------------------
     343
     344You can overide the ``clean()`` method on a model form to provide additional
     345validation in the same way you can on a normal form.  However, by default the
     346``clean()`` method validates the uniqueness of fields that are marked as unique
     347on the model, and those marked as unque_together, if you would like to overide
     348the ``clean()`` method and maintain the default validation you must call the
     349parent class's ``clean()`` method.
     350
    341351Form inheritance
    342352----------------
    343353
    books of a specific author. Here is how you could accomplish this:: 
    500510    >>> from django.forms.models import inlineformset_factory
    501511    >>> BookFormSet = inlineformset_factory(Author, Book)
    502512    >>> author = Author.objects.get(name=u'Orson Scott Card')
    503     >>> formset = BookFormSet(instance=author)
    504  No newline at end of file
     513    >>> formset = BookFormSet(instance=author)
  • tests/modeltests/model_forms/models.py

    diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
    index 5f714fb..a74b3d3 100644
    a b class CommaSeparatedInteger(models.Model): 
    117117    def __unicode__(self):
    118118        return self.field
    119119
     120class Unique(models.Model):
     121    unique_field = models.CharField(max_length=100, unique=True)
     122
     123class UniqueTogether(models.Model):
     124    unique_field_1 = models.CharField(max_length=100)
     125    unique_field_2 = models.CharField(max_length=100)
     126   
     127    class Meta:
     128        unique_together = (('unique_field_1', 'unique_field_2'),)
     129
    120130class ArticleStatus(models.Model):
    121131    status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True)
    122132
     133
    123134__test__ = {'API_TESTS': """
    124135>>> from django import forms
    125136>>> from django.forms.models import ModelForm, model_to_dict
    u'1,,2' 
    11321143>>> f.clean('1')
    11331144u'1'
    11341145
    1135 # Choices on CharField and IntegerField
     1146>>> class UniqueForm(ModelForm):
     1147...     class Meta:
     1148...         model = Unique
     1149>>> form1 = UniqueForm({'unique_field': 'unique'})
     1150>>> form1.is_valid()
     1151True
     1152>>> obj = form1.save()
     1153>>> obj
     1154<Unique: Unique object>
     1155>>> form2 = UniqueForm({'unique_field': 'unique'})
     1156>>> form2.is_valid()
     1157False
     1158>>> form2._errors
     1159{'unique_field': [u'Unique with this Unique field already exists.']}
     1160>>> form3 = UniqueForm({'unique_field': 'unique'}, instance=obj)
     1161>>> form3.is_valid()
     1162True
    11361163
     1164# ModelForm test of unique_together constraint
     1165>>> class UniqueTogetherForm(ModelForm):
     1166...     class Meta:
     1167...         model = UniqueTogether
     1168>>> form1 = UniqueTogetherForm({'unique_field_1': 'unique1', 'unique_field_2': 'unique2'})
     1169>>> form1.is_valid()
     1170True
     1171>>> form1.save()
     1172<UniqueTogether: UniqueTogether object>
     1173>>> form2 = UniqueTogetherForm({'unique_field_1': 'unique1', 'unique_field_2': 'unique2'})
     1174>>> form2.is_valid()
     1175False
     1176>>> form2._errors
     1177{'__all__': [u'Unique Together with this Unique field 1 and Unique field 2 already exists.']}
     1178
     1179# Choices on CharField and IntegerField
    11371180>>> class ArticleForm(ModelForm):
    11381181...     class Meta:
    11391182...         model = Article
Back to Top