Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

magic-removal: Some validation fixes.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1797 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 85ef615c42969d92789cd6fc4dada23379618a68 1 parent 8fae408
@rjwittams rjwittams authored
View
48 django/contrib/admin/views/stages/change.py
@@ -49,41 +49,43 @@ def change_stage(request, path, object_id):
#save a copy of the data to use for errors later.
data = new_data.copy()
-
manipulator.do_html2python(new_data)
#update the manipulator with the effects of previous commands.
manipulator.update(new_data)
#get the errors on the updated shape of the manipulator
#HACK - validators should not work on POSTED data directly...
- errors = manipulator.get_validation_errors(data)
+
if request.POST.has_key("_preview"):
- pass
+ errors = manipulator.get_validation_errors(data)
elif request.POST.has_key("command"):
command_name = request.POST.get("command")
manipulator.do_command(command_name)
- new_data = manipulator.flatten_data()
- elif errors:
+ errors = manipulator.get_validation_errors(data)
new_data = manipulator.flatten_data()
else:
- new_object = manipulator.save_from_update()
- log_change_message(request.user, opts, manipulator, new_object)
- msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
- pk_value = getattr(new_object, opts.pk.attname)
- if request.POST.has_key("_continue"):
- request.user.add_message(msg + ' ' + _("You may edit it again below."))
- if request.REQUEST.has_key('_popup'):
- return HttpResponseRedirect(request.path + "?_popup=1")
- else:
- return HttpResponseRedirect(request.path)
- elif request.POST.has_key("_saveasnew"):
- request.user.add_message(_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
- return HttpResponseRedirect("../../%s/" % pk_value)
- elif request.POST.has_key("_addanother"):
- request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
- return HttpResponseRedirect("../../add/")
+ errors = manipulator.get_validation_errors(data)
+ if errors:
+ new_data = manipulator.flatten_data()
else:
- request.user.add_message(msg)
- return HttpResponseRedirect("../../")
+ new_object = manipulator.save_from_update()
+ log_change_message(request.user, opts, manipulator, new_object)
+ msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+ pk_value = getattr(new_object, opts.pk.attname)
+ if request.POST.has_key("_continue"):
+ request.user.add_message(msg + ' ' + _("You may edit it again below."))
+ if request.REQUEST.has_key('_popup'):
+ return HttpResponseRedirect(request.path + "?_popup=1")
+ else:
+ return HttpResponseRedirect(request.path)
+ elif request.POST.has_key("_saveasnew"):
+ request.user.add_message(_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
+ return HttpResponseRedirect("../../%s/" % pk_value)
+ elif request.POST.has_key("_addanother"):
+ request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+ return HttpResponseRedirect("../../add/")
+ else:
+ request.user.add_message(msg)
+ return HttpResponseRedirect("../../")
else:
# Populate new_data with a "flattened" version of the current data.
new_data = manipulator.flatten_data()
View
87 django/core/formfields.py
@@ -55,26 +55,35 @@ def get_validation_errors(self, new_data):
"Returns dictionary mapping field_names to error-message lists"
errors = {}
for field in self.fields:
- if field.is_required and not new_data.get(field.field_name, False):
- errors.setdefault(field.field_name, []).append(gettext_lazy('This field is required.'))
- continue
- try:
- validator_list = field.validator_list
- if hasattr(self, 'validate_%s' % field.field_name):
- validator_list.append(getattr(self, 'validate_%s' % field.field_name))
- for validator in validator_list:
- if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
- try:
- if hasattr(field, 'requires_data_list'):
- validator(new_data.getlist(field.field_name), new_data)
- else:
- validator(new_data.get(field.field_name, ''), new_data)
- except validators.ValidationError, e:
- errors.setdefault(field.field_name, []).extend(e.messages)
- # If a CriticalValidationError is raised, ignore any other ValidationErrors
- # for this particular field
- except validators.CriticalValidationError, e:
- errors.setdefault(field.field_name, []).extend(e.messages)
+ errors.update(field.get_validation_errors(new_data))
+ val_name = 'validate_%s' % field.field_name
+ if hasattr(self, val_name):
+ val = getattr(self, val_name)
+ try:
+ field.run_validator(new_data, val)
+ except (validators.ValidationError, validators.CriticalValidationError), e:
+ errors.setdefault(field.field_name, []).extend(e.messages)
+
+# if field.is_required and not new_data.get(field.field_name, False):
+# errors.setdefault(field.field_name, []).append(gettext_lazy('This field is required.'))
+# continue
+# try:
+# validator_list = field.validator_list
+# if hasattr(self, 'validate_%s' % field.field_name):
+# validator_list.append(getattr(self, 'validate_%s' % field.field_name))
+# for validator in validator_list:
+# if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
+# try:
+# if hasattr(field, 'requires_data_list'):
+# validator(new_data.getlist(field.field_name), new_data)
+# else:
+# validator(new_data.get(field.field_name, ''), new_data)
+# except validators.ValidationError, e:
+# errors.setdefault(field.field_name, []).extend(e.messages)
+# # If a CriticalValidationError is raised, ignore any other ValidationErrors
+# # for this particular field
+# except validators.CriticalValidationError, e:
+# errors.setdefault(field.field_name, []).extend(e.messages)
return errors
def save(self, new_data):
@@ -89,6 +98,7 @@ def do_html2python(self, new_data):
must happen after validation because html2python functions aren't
expected to deal with invalid input.
"""
+ print "converting for ", self, self.fields
for field in self.fields:
field.convert_post_data(new_data)
@@ -314,12 +324,37 @@ def convert_post_data(self, new_data):
except ValueError:
converted_data = d
new_data.setlist(name, converted_data)
-# else:
-# try:
-# # individual fields deal with None values themselves
-# new_data.setlist(name, [self.__class__.html2python(None)])
-# except EmptyValue:
-# new_data.setlist(name, [])
+ else:
+ try:
+ #individual fields deal with None values themselves
+ new_data.setlist(name, [self.__class__.html2python(None)])
+ except EmptyValue:
+ new_data.setlist(name, [])
+
+
+ def run_validator(self, new_data, validator):
+ if self.is_required or new_data.get(self.field_name, False) or hasattr(validator, 'always_test'):
+ if hasattr(self, 'requires_data_list'):
+ validator(new_data.getlist(self.field_name), new_data)
+ else:
+ validator(new_data.get(self.field_name, ''), new_data)
+
+ def get_validation_errors(self, new_data):
+ errors = {}
+ if self.is_required and not new_data.get(self.field_name, False):
+ errors.setdefault(self.field_name, []).append(gettext_lazy('This field is required.'))
+ return errors
+ try:
+ for validator in self.validator_list:
+ try:
+ self.run_validator(new_data, validator)
+ except validators.ValidationError, e:
+ errors.setdefault(self.field_name, []).extend(e.messages)
+ # If a CriticalValidationError is raised, ignore any other ValidationErrors
+ # for this particular field
+ except validators.CriticalValidationError, e:
+ errors.setdefault(self.field_name, []).extend(e.messages)
+ return errors
def get_id(self):
"Returns the HTML 'id' attribute for this form field."
View
4 django/db/models/base.py
@@ -1,6 +1,6 @@
import django.db.models.manipulators
import django.db.models.manager
-from django.db.models.fields import AutoField, ImageField
+from django.db.models.fields import AutoField, ImageField, Admin
from django.db.models.fields.related import OneToOne, ManyToOne
from django.db.models.related import RelatedObject
from django.db.models.query import orderlist2sql
@@ -20,7 +20,7 @@
if not hasattr(__builtins__, 'set'):
from sets import Set as set
-attribute_transforms = {}
+attribute_transforms = { 'Admin': lambda cls: Admin(**cls.__dict__) }
class ModelBase(type):
"Metaclass for all models"
View
5 django/db/models/fields/__init__.py
@@ -726,7 +726,7 @@ def get_internal_type(self):
return "IntegerField"
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
- return [HiddenField(name_prefix + self.name) ]
+ return [formfields.HiddenField(name_prefix + self.name) ]
def contribute_to_class(self, cls, name):
super(OrderingField, self ).contribute_to_class(cls, name)
@@ -819,3 +819,6 @@ def get_field_sets(self, opts):
line_specs = fs_options['fields']
new_fieldset_list.append(FieldSet(name, classes, opts.get_field, line_specs))
return new_fieldset_list
+
+ def contribute_to_class(self, cls, name):
+ cls._meta.admin = self
View
53 django/db/models/manipulators.py
@@ -99,20 +99,38 @@ def __init__(self, original_object=None, follow=None, name_parts=() ):
if manipulators != None:
self.children[f] = manipulators
self.needs_deletion = False
+ self.ignore_errors = False
def get_fields(self):
- if self.needs_deletion:
+ if self.needs_deletion :
return []
else:
- l = list(self.fields_)
- for child_manips in self.children.values():
- for manip in child_manips:
- if manip:
- l.extend(manip.fields)
- return l
+ return self.fields_
+ #l = list(self.fields_)
+ #for child_manips in self.children.values():
+ # for manip in child_manips:
+ # if manip:
+ # l.extend(manip.fields)
+ #return l
fields = property(get_fields)
+ def get_validation_errors(self, new_data):
+ "Returns dictionary mapping field_names to error-message lists"
+ if self.needs_deletion or self.ignore_errors:
+ return {}
+
+ errors = super(AutomaticManipulator, self).get_validation_errors(new_data)
+
+ for manips in self.children.values():
+ errors.update(manips.get_validation_errors(new_data))
+ return errors
+
+ def do_html2python(self, new_data):
+ super(AutomaticManipulator, self).do_html2python(new_data)
+ for child in self.children.values():
+ child.do_html2python(new_data)
+
def get_original_value(self, field):
raise NotImplemented
@@ -358,6 +376,8 @@ def _fill_data(self, expanded_data):
items.sort(cmp = lambda x, y: cmp(x[0], y[0]))
for index, obj_data in items:
child_manip = self.add_child(index)
+ #HACK: this data will not have been converted to python form yet.
+ #child_manip.do_html2python(obj_data)
child_manip._fill_data(obj_data)
def _do_command_expanded(self, command_parts):
@@ -384,7 +404,9 @@ def _do_command_expanded(self, command_parts):
# add.
# TODO: page.forward, page.back, page.n, swap.n.m
if command_name == "add":
- self.add_child()
+ child_manip = self.add_child()
+ # Don't show validation stuff for things just added.
+ child_manip.ignore_errors = True
elif command_name == "swap":
order_field = self.model._meta.order_with_respect_to
if not order_field:
@@ -417,6 +439,7 @@ def add_child(self, index = None):
prefix = '%s%s.' % (self.name_prefix, index )
child_manip = man_class(self.follow, self.name_parts + ( str(index), ) )
+
self[index] = child_manip
return child_manip
@@ -427,6 +450,20 @@ def flatten_data(self):
manip_data = manip.flatten_data()
new_data.update(manip_data)
return new_data
+
+ def get_validation_errors(self, new_data):
+ "Returns dictionary mapping field_names to error-message lists"
+ errors = {}
+ for manip in self:
+ if manip:
+ errors.update(manip.get_validation_errors(new_data))
+ return errors
+
+ def do_html2python(self, new_data):
+ print "coll: ", self
+ for manip in self:
+ if manip:
+ manip.do_html2python(new_data)
def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
from django.db.models.fields.related import ManyToOne
Please sign in to comment.
Something went wrong with that request. Please try again.