mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Support datetime in admin pickle widgets/forms
This commit is contained in:
parent
5064242ef8
commit
3416db98d7
1 changed files with 40 additions and 22 deletions
|
|
@ -30,6 +30,7 @@ Modified for Evennia by Griatch and the Evennia community.
|
|||
"""
|
||||
from builtins import object
|
||||
from ast import literal_eval
|
||||
from datetime import datetime
|
||||
|
||||
from copy import deepcopy
|
||||
from base64 import b64encode, b64decode
|
||||
|
|
@ -38,9 +39,8 @@ from zlib import compress, decompress
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
|
||||
from django.forms import CharField, Textarea
|
||||
from django.forms.utils import flatatt
|
||||
from django.utils.html import format_html
|
||||
from django.forms.fields import CharField
|
||||
from django.forms.widgets import Textarea
|
||||
|
||||
from pickle import loads, dumps
|
||||
from django.utils.encoding import force_text
|
||||
|
|
@ -107,36 +107,41 @@ def dbsafe_decode(value, compress_object=False):
|
|||
|
||||
|
||||
class PickledWidget(Textarea):
|
||||
"""
|
||||
This is responsible for outputting HTML representing a given field.
|
||||
"""
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
"""Display of the PickledField in django admin"""
|
||||
|
||||
value = repr(value)
|
||||
try:
|
||||
# necessary to convert it back after repr(), otherwise validation errors will mutate it
|
||||
value = literal_eval(value)
|
||||
except ValueError:
|
||||
return value
|
||||
repr_value = repr(value)
|
||||
|
||||
# fix since the signature of build_attrs changed in Django 1.11
|
||||
# analyze represented value to see how big the field should be
|
||||
if attrs is not None:
|
||||
attrs["name"] = name
|
||||
else:
|
||||
attrs = {"name": name}
|
||||
attrs['cols'] = 30
|
||||
# adapt rows to width
|
||||
# adapt number of rows to number of lines in string
|
||||
rows = 1
|
||||
if isinstance(value, str) and "\n" in value:
|
||||
if isinstance(value, str) and "\n" in repr_value:
|
||||
rows = max(1, len(value.split('\n')))
|
||||
attrs['rows'] = rows
|
||||
attrs = self.build_attrs(attrs)
|
||||
|
||||
try:
|
||||
# necessary to convert it back after repr(), otherwise validation errors will mutate it
|
||||
value = literal_eval(repr_value)
|
||||
except ValueError:
|
||||
pass
|
||||
return super().render(name, value, attrs=attrs, renderer=renderer)
|
||||
# return format_html('<textarea{0}>\r\n{1}</textarea>',
|
||||
# flatatt(final_attrs),
|
||||
# value)
|
||||
|
||||
|
||||
class PickledFormField(CharField):
|
||||
"""
|
||||
This represents one input field for the form.
|
||||
|
||||
"""
|
||||
|
||||
widget = PickledWidget
|
||||
default_error_messages = dict(CharField.default_error_messages)
|
||||
default_error_messages['invalid'] = (
|
||||
|
|
@ -146,27 +151,40 @@ class PickledFormField(CharField):
|
|||
"surrounded by quote marks. We have converted it to a string for your "
|
||||
"convenience. If it is acceptable, please hit save again.")
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# This needs to fall through to literal_eval.
|
||||
kwargs['required'] = False
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super().clean(value)
|
||||
|
||||
# handle empty input
|
||||
try:
|
||||
if not value.strip():
|
||||
# Field was left blank. Make this None.
|
||||
value = 'None'
|
||||
except AttributeError:
|
||||
value = 'None'
|
||||
pass
|
||||
|
||||
# parse raw Python
|
||||
try:
|
||||
return literal_eval(value)
|
||||
except (ValueError, SyntaxError):
|
||||
try:
|
||||
value = repr(value)
|
||||
return literal_eval(value)
|
||||
except (ValueError, SyntaxError):
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
pass
|
||||
|
||||
# handle datetime objects
|
||||
try:
|
||||
return datetime.strptime(value, "%Y-%m-%d %H:%M:%S.%f")
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# fall through to parsing the repr() of the data
|
||||
try:
|
||||
value = repr(value)
|
||||
return literal_eval(value)
|
||||
except (ValueError, SyntaxError):
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
|
||||
class PickledObjectField(models.Field):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue