magic-removal: Some validation fixes.
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1797 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
8fae40894a
commit
85ef615c42
|
@ -49,41 +49,43 @@ def change_stage(request, path, object_id):
|
||||||
|
|
||||||
#save a copy of the data to use for errors later.
|
#save a copy of the data to use for errors later.
|
||||||
data = new_data.copy()
|
data = new_data.copy()
|
||||||
|
|
||||||
manipulator.do_html2python(new_data)
|
manipulator.do_html2python(new_data)
|
||||||
#update the manipulator with the effects of previous commands.
|
#update the manipulator with the effects of previous commands.
|
||||||
manipulator.update(new_data)
|
manipulator.update(new_data)
|
||||||
#get the errors on the updated shape of the manipulator
|
#get the errors on the updated shape of the manipulator
|
||||||
#HACK - validators should not work on POSTED data directly...
|
#HACK - validators should not work on POSTED data directly...
|
||||||
errors = manipulator.get_validation_errors(data)
|
|
||||||
if request.POST.has_key("_preview"):
|
if request.POST.has_key("_preview"):
|
||||||
pass
|
errors = manipulator.get_validation_errors(data)
|
||||||
elif request.POST.has_key("command"):
|
elif request.POST.has_key("command"):
|
||||||
command_name = request.POST.get("command")
|
command_name = request.POST.get("command")
|
||||||
manipulator.do_command(command_name)
|
manipulator.do_command(command_name)
|
||||||
new_data = manipulator.flatten_data()
|
errors = manipulator.get_validation_errors(data)
|
||||||
elif errors:
|
|
||||||
new_data = manipulator.flatten_data()
|
new_data = manipulator.flatten_data()
|
||||||
else:
|
else:
|
||||||
new_object = manipulator.save_from_update()
|
errors = manipulator.get_validation_errors(data)
|
||||||
log_change_message(request.user, opts, manipulator, new_object)
|
if errors:
|
||||||
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
|
new_data = manipulator.flatten_data()
|
||||||
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:
|
else:
|
||||||
request.user.add_message(msg)
|
new_object = manipulator.save_from_update()
|
||||||
return HttpResponseRedirect("../../")
|
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:
|
else:
|
||||||
# Populate new_data with a "flattened" version of the current data.
|
# Populate new_data with a "flattened" version of the current data.
|
||||||
new_data = manipulator.flatten_data()
|
new_data = manipulator.flatten_data()
|
||||||
|
|
|
@ -55,26 +55,35 @@ class Manipulator(object):
|
||||||
"Returns dictionary mapping field_names to error-message lists"
|
"Returns dictionary mapping field_names to error-message lists"
|
||||||
errors = {}
|
errors = {}
|
||||||
for field in self.fields:
|
for field in self.fields:
|
||||||
if field.is_required and not new_data.get(field.field_name, False):
|
errors.update(field.get_validation_errors(new_data))
|
||||||
errors.setdefault(field.field_name, []).append(gettext_lazy('This field is required.'))
|
val_name = 'validate_%s' % field.field_name
|
||||||
continue
|
if hasattr(self, val_name):
|
||||||
try:
|
val = getattr(self, val_name)
|
||||||
validator_list = field.validator_list
|
try:
|
||||||
if hasattr(self, 'validate_%s' % field.field_name):
|
field.run_validator(new_data, val)
|
||||||
validator_list.append(getattr(self, 'validate_%s' % field.field_name))
|
except (validators.ValidationError, validators.CriticalValidationError), e:
|
||||||
for validator in validator_list:
|
errors.setdefault(field.field_name, []).extend(e.messages)
|
||||||
if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
|
|
||||||
try:
|
# if field.is_required and not new_data.get(field.field_name, False):
|
||||||
if hasattr(field, 'requires_data_list'):
|
# errors.setdefault(field.field_name, []).append(gettext_lazy('This field is required.'))
|
||||||
validator(new_data.getlist(field.field_name), new_data)
|
# continue
|
||||||
else:
|
# try:
|
||||||
validator(new_data.get(field.field_name, ''), new_data)
|
# validator_list = field.validator_list
|
||||||
except validators.ValidationError, e:
|
# if hasattr(self, 'validate_%s' % field.field_name):
|
||||||
errors.setdefault(field.field_name, []).extend(e.messages)
|
# validator_list.append(getattr(self, 'validate_%s' % field.field_name))
|
||||||
# If a CriticalValidationError is raised, ignore any other ValidationErrors
|
# for validator in validator_list:
|
||||||
# for this particular field
|
# if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
|
||||||
except validators.CriticalValidationError, e:
|
# try:
|
||||||
errors.setdefault(field.field_name, []).extend(e.messages)
|
# 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
|
return errors
|
||||||
|
|
||||||
def save(self, new_data):
|
def save(self, new_data):
|
||||||
|
@ -89,6 +98,7 @@ class Manipulator(object):
|
||||||
must happen after validation because html2python functions aren't
|
must happen after validation because html2python functions aren't
|
||||||
expected to deal with invalid input.
|
expected to deal with invalid input.
|
||||||
"""
|
"""
|
||||||
|
print "converting for ", self, self.fields
|
||||||
for field in self.fields:
|
for field in self.fields:
|
||||||
field.convert_post_data(new_data)
|
field.convert_post_data(new_data)
|
||||||
|
|
||||||
|
@ -314,12 +324,37 @@ class FormField:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
converted_data = d
|
converted_data = d
|
||||||
new_data.setlist(name, converted_data)
|
new_data.setlist(name, converted_data)
|
||||||
# else:
|
else:
|
||||||
# try:
|
try:
|
||||||
# # individual fields deal with None values themselves
|
#individual fields deal with None values themselves
|
||||||
# new_data.setlist(name, [self.__class__.html2python(None)])
|
new_data.setlist(name, [self.__class__.html2python(None)])
|
||||||
# except EmptyValue:
|
except EmptyValue:
|
||||||
# new_data.setlist(name, [])
|
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):
|
def get_id(self):
|
||||||
"Returns the HTML 'id' attribute for this form field."
|
"Returns the HTML 'id' attribute for this form field."
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import django.db.models.manipulators
|
import django.db.models.manipulators
|
||||||
import django.db.models.manager
|
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.fields.related import OneToOne, ManyToOne
|
||||||
from django.db.models.related import RelatedObject
|
from django.db.models.related import RelatedObject
|
||||||
from django.db.models.query import orderlist2sql
|
from django.db.models.query import orderlist2sql
|
||||||
|
@ -20,7 +20,7 @@ import os
|
||||||
if not hasattr(__builtins__, 'set'):
|
if not hasattr(__builtins__, 'set'):
|
||||||
from sets import Set as set
|
from sets import Set as set
|
||||||
|
|
||||||
attribute_transforms = {}
|
attribute_transforms = { 'Admin': lambda cls: Admin(**cls.__dict__) }
|
||||||
|
|
||||||
class ModelBase(type):
|
class ModelBase(type):
|
||||||
"Metaclass for all models"
|
"Metaclass for all models"
|
||||||
|
|
|
@ -726,7 +726,7 @@ class OrderingField(IntegerField):
|
||||||
return "IntegerField"
|
return "IntegerField"
|
||||||
|
|
||||||
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
|
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):
|
def contribute_to_class(self, cls, name):
|
||||||
super(OrderingField, self ).contribute_to_class(cls, name)
|
super(OrderingField, self ).contribute_to_class(cls, name)
|
||||||
|
@ -819,3 +819,6 @@ class Admin:
|
||||||
line_specs = fs_options['fields']
|
line_specs = fs_options['fields']
|
||||||
new_fieldset_list.append(FieldSet(name, classes, opts.get_field, line_specs))
|
new_fieldset_list.append(FieldSet(name, classes, opts.get_field, line_specs))
|
||||||
return new_fieldset_list
|
return new_fieldset_list
|
||||||
|
|
||||||
|
def contribute_to_class(self, cls, name):
|
||||||
|
cls._meta.admin = self
|
|
@ -99,20 +99,38 @@ class AutomaticManipulator(Manipulator, Naming):
|
||||||
if manipulators != None:
|
if manipulators != None:
|
||||||
self.children[f] = manipulators
|
self.children[f] = manipulators
|
||||||
self.needs_deletion = False
|
self.needs_deletion = False
|
||||||
|
self.ignore_errors = False
|
||||||
|
|
||||||
def get_fields(self):
|
def get_fields(self):
|
||||||
if self.needs_deletion:
|
if self.needs_deletion :
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
l = list(self.fields_)
|
return self.fields_
|
||||||
for child_manips in self.children.values():
|
#l = list(self.fields_)
|
||||||
for manip in child_manips:
|
#for child_manips in self.children.values():
|
||||||
if manip:
|
# for manip in child_manips:
|
||||||
l.extend(manip.fields)
|
# if manip:
|
||||||
return l
|
# l.extend(manip.fields)
|
||||||
|
#return l
|
||||||
|
|
||||||
fields = property(get_fields)
|
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):
|
def get_original_value(self, field):
|
||||||
raise NotImplemented
|
raise NotImplemented
|
||||||
|
|
||||||
|
@ -358,6 +376,8 @@ class ManipulatorCollection(list, Naming):
|
||||||
items.sort(cmp = lambda x, y: cmp(x[0], y[0]))
|
items.sort(cmp = lambda x, y: cmp(x[0], y[0]))
|
||||||
for index, obj_data in items:
|
for index, obj_data in items:
|
||||||
child_manip = self.add_child(index)
|
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)
|
child_manip._fill_data(obj_data)
|
||||||
|
|
||||||
def _do_command_expanded(self, command_parts):
|
def _do_command_expanded(self, command_parts):
|
||||||
|
@ -384,7 +404,9 @@ class ManipulatorCollection(list, Naming):
|
||||||
# add.
|
# add.
|
||||||
# TODO: page.forward, page.back, page.n, swap.n.m
|
# TODO: page.forward, page.back, page.n, swap.n.m
|
||||||
if command_name == "add":
|
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":
|
elif command_name == "swap":
|
||||||
order_field = self.model._meta.order_with_respect_to
|
order_field = self.model._meta.order_with_respect_to
|
||||||
if not order_field:
|
if not order_field:
|
||||||
|
@ -417,6 +439,7 @@ class ManipulatorCollection(list, Naming):
|
||||||
|
|
||||||
prefix = '%s%s.' % (self.name_prefix, index )
|
prefix = '%s%s.' % (self.name_prefix, index )
|
||||||
child_manip = man_class(self.follow, self.name_parts + ( str(index), ) )
|
child_manip = man_class(self.follow, self.name_parts + ( str(index), ) )
|
||||||
|
|
||||||
self[index] = child_manip
|
self[index] = child_manip
|
||||||
return child_manip
|
return child_manip
|
||||||
|
|
||||||
|
@ -427,6 +450,20 @@ class ManipulatorCollection(list, Naming):
|
||||||
manip_data = manip.flatten_data()
|
manip_data = manip.flatten_data()
|
||||||
new_data.update(manip_data)
|
new_data.update(manip_data)
|
||||||
return new_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):
|
def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
|
||||||
from django.db.models.fields.related import ManyToOne
|
from django.db.models.fields.related import ManyToOne
|
||||||
|
|
Loading…
Reference in New Issue