From ab6b7680a1731cee27403ba41390feeb6a6ebcf9 Mon Sep 17 00:00:00 2001 From: Tehom Date: Fri, 18 Nov 2016 04:56:31 -0500 Subject: [PATCH] Made validation error in picklefield attempt to convert strings to a format it will accept before raising an error. Made validation errors in AttributeAdmin just raise a server error in order to prevent the force-text conversion of default fields for the forms, leading to buggy values. --- evennia/typeclasses/admin.py | 13 +++++++++---- evennia/utils/picklefield.py | 8 ++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/evennia/typeclasses/admin.py b/evennia/typeclasses/admin.py index b7a72e8357..cec23dfc0e 100644 --- a/evennia/typeclasses/admin.py +++ b/evennia/typeclasses/admin.py @@ -1,6 +1,5 @@ from django.contrib import admin -from django.contrib.admin import ModelAdmin -from evennia.typeclasses.models import Attribute, Tag +from evennia.typeclasses.models import Tag from django import forms from evennia.utils.picklefield import PickledFormField from evennia.utils.dbserialize import from_pickle @@ -200,8 +199,7 @@ class AttributeForm(forms.ModelForm): differently than None objects. So for consistency with how things are handled in game, we'll try to make sure that empty form fields will be None, rather than ''. """ - # we are spoofing a tag for the Handler that will be called - # instance = super(TagForm, self).save(commit=False) + # we are spoofing an Attribute for the Handler that will be called instance = self.instance instance.attr_key = self.cleaned_data['attr_key'] instance.attr_category = self.cleaned_data['attr_category'] or None @@ -218,6 +216,13 @@ class AttributeFormSet(forms.BaseInlineFormSet): """ Attribute version of TagFormSet, as above. """ + def clean(self): + if any(self.errors): + from django.core.exceptions import FieldError + raise FieldError("Sorry, there was an error in saving that form. You may have forgotten to add a name " + "for the Attribute, or you may have provided an invalid literal for an Attribute's value.") + super(AttributeFormSet, self).clean() + def save(self, commit=True): def get_handler(finished_object): related = getattr(finished_object, self.related_field) diff --git a/evennia/utils/picklefield.py b/evennia/utils/picklefield.py index 0b9250c613..59db2e44c2 100644 --- a/evennia/utils/picklefield.py +++ b/evennia/utils/picklefield.py @@ -147,13 +147,17 @@ class PickledFormField(CharField): super(PickledFormField, self).__init__(*args, **kwargs) def clean(self, value): - if value == '': + if not value.strip(): # Field was left blank. Make this None. value = 'None' try: return literal_eval(value) except (ValueError, SyntaxError): - raise ValidationError(self.error_messages['invalid']) + try: + value = "u'%s'" % force_text(value) + return literal_eval(value) + except (ValueError, SyntaxError): + raise ValidationError(self.error_messages['invalid']) class PickledObjectField(models.Field):