Ticket #8209: django-r8769-8209.2.diff
File django-r8769-8209.2.diff, 5.7 KB (added by , 16 years ago) |
---|
-
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): 202 202 object_data.update(initial) 203 203 super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data, 204 204 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) 205 238 206 239 def save(self, commit=True): 207 240 """ -
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:: 338 338 ... class Meta: 339 339 ... model = Article 340 340 341 Overriding the clean() method 342 ----------------------------- 343 344 You can overide the ``clean()`` method on a model form to provide additional 345 validation 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 347 on the model, and those marked as unque_together, if you would like to overide 348 the ``clean()`` method and maintain the default validation you must call the 349 parent class's ``clean()`` method. 350 341 351 Form inheritance 342 352 ---------------- 343 353 … … books of a specific author. Here is how you could accomplish this:: 500 510 >>> from django.forms.models import inlineformset_factory 501 511 >>> BookFormSet = inlineformset_factory(Author, Book) 502 512 >>> 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): 117 117 def __unicode__(self): 118 118 return self.field 119 119 120 class Unique(models.Model): 121 unique_field = models.CharField(max_length=100, unique=True) 122 123 class 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 120 130 class ArticleStatus(models.Model): 121 131 status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) 122 132 133 123 134 __test__ = {'API_TESTS': """ 124 135 >>> from django import forms 125 136 >>> from django.forms.models import ModelForm, model_to_dict … … u'1,,2' 1132 1143 >>> f.clean('1') 1133 1144 u'1' 1134 1145 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() 1151 True 1152 >>> obj = form1.save() 1153 >>> obj 1154 <Unique: Unique object> 1155 >>> form2 = UniqueForm({'unique_field': 'unique'}) 1156 >>> form2.is_valid() 1157 False 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() 1162 True 1136 1163 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() 1170 True 1171 >>> form1.save() 1172 <UniqueTogether: UniqueTogether object> 1173 >>> form2 = UniqueTogetherForm({'unique_field_1': 'unique1', 'unique_field_2': 'unique2'}) 1174 >>> form2.is_valid() 1175 False 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 1137 1180 >>> class ArticleForm(ModelForm): 1138 1181 ... class Meta: 1139 1182 ... model = Article