Ticket #5150: unique.diff
File unique.diff, 3.4 KB (added by , 17 years ago) |
---|
-
django/newforms/models.py
3 3 and database field objects. 4 4 """ 5 5 6 from django.utils.text import capfirst 6 7 from django.utils.translation import ugettext 7 8 from django.utils.encoding import smart_unicode 8 9 … … 66 67 return save_instance(self, instance, fields, fail_message, commit) 67 68 return save 68 69 70 def make_unique_check(field, form, pk_val=None): 71 "Returns a clean_%s() method for a Form." 72 def check_unique(self): 73 # if parent class also has clean_ method, then call it 74 parent = super(form, self) 75 if hasattr(parent, 'clean_%s' % field.name): 76 value = getattr(parent, 'clean_%s' % field.name)() 77 else: 78 value = self.cleaned_data[field.name] 79 queryset = self._model.objects.filter(**{field.name: value}) 80 if pk_val is not None: 81 queryset = queryset.exclude(pk=pk_val) 82 if queryset.count() > 0: 83 raise ValidationError(ugettext(u'%s with this %s already exists.') % (capfirst(self._model._meta.verbose_name), field.verbose_name)) 84 return value 85 return check_unique 86 69 87 def form_for_model(model, form=BaseForm, fields=None, formfield_callback=lambda f: f.formfield()): 70 88 """ 71 89 Returns a Form class for the given Django model class. … … 78 96 """ 79 97 opts = model._meta 80 98 field_list = [] 99 clean_methods = {} 81 100 for f in opts.fields + opts.many_to_many: 82 101 if not f.editable: 83 102 continue 84 103 if fields and not f.name in fields: 85 104 continue 86 formfield = formfield_callback(f )105 formfield = formfield_callback(f, initial=f.get_default()) 87 106 if formfield: 88 107 field_list.append((f.name, formfield)) 108 if f.unique: 109 clean_methods['clean_%s' % f.name] = make_unique_check(f, form) 89 110 base_fields = SortedDictFromList(field_list) 90 111 return type(opts.object_name + 'Form', (form,), 91 {'base_fields': base_fields, '_model': model, 'save': make_model_save(model, fields, 'created')})112 dict({'base_fields': base_fields, '_model': model, 'save': make_model_save(model, fields, 'created')}, **clean_methods)) 92 113 93 114 def form_for_instance(instance, form=BaseForm, fields=None, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)): 94 115 """ … … 104 125 model = instance.__class__ 105 126 opts = model._meta 106 127 field_list = [] 128 clean_methods = {} 107 129 for f in opts.fields + opts.many_to_many: 108 130 if not f.editable: 109 131 continue … … 113 135 formfield = formfield_callback(f, initial=current_value) 114 136 if formfield: 115 137 field_list.append((f.name, formfield)) 138 if f.unique: 139 clean_methods['clean_%s' % f.name] = make_unique_check(f, form, instance._get_pk_val()) 116 140 base_fields = SortedDictFromList(field_list) 117 141 return type(opts.object_name + 'InstanceForm', (form,), 118 {'base_fields': base_fields, '_model': model, 'save': make_instance_save(instance, fields, 'changed')})142 dict({'base_fields': base_fields, '_model': model, 'save': make_instance_save(instance, fields, 'changed')}, **clean_methods)) 119 143 120 144 def form_for_fields(field_list): 121 145 "Returns a Form class for the given list of Django database field instances."