Важнее некуда: В PickleField добавлена возможность полноценного хранения объектов моделей и поддержка питоновских значений по умолчанию.
Важно: предыдущая версия PickleField
'а была практически неработающей в большинстве случаев. Теперь же появилось время в связи с ангиной, и я быстро исправил эту оплошность.
Иногда возникает необходимость хранить какие-то данные, "сериализированные" с помощью pickle или cPickle, в базе данных. Для этих случаев весьма кстати будет PickleField
. Вообщем, может быть кому-то пригодится.
from django.conf import settings from django.db import models if getattr(settings, 'USE_CPICKLE', False): import cPickle as pickle else: import pickle class PickleField(models.TextField): __metaclass__ = models.SubfieldBase editable = False serialize = False def get_db_prep_value(self, value): return pickle.dumps(value) def to_python(self, value): if not isinstance(value, basestring): return value # Tries to convert unicode objects to string, cause loads pickle from # unicode excepts ugly ``KeyError: '\x00'``. # # If not possible, return this value, cause it's not pickled yet. if isinstance(value, unicode): try: str_value = str(value) except UnicodeEncodeError: return value else: str_value = value try: return pickle.loads(str_value) except ValueError: # If pickle could not loads from string it's means that it's Python # string saved to PickleField. return value
Также добавил простейший тест для показания работы PickleField
'a:
import unittest from django.db import models from fields import PickleField class PickleObject(models.Model): name = models.CharField(max_length=16) data = PickleField() class TestPickleField(unittest.TestCase): def setUp(self): PickleObject.objects.all().delete() def test_not_string_data(self): items = [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5' ] obj = PickleObject.objects.create(name='default', data=items) self.assertEqual(PickleObject.objects.count(), 1) self.assertEqual(obj.data, items) obj = PickleObject.objects.get(name='default') self.assertEqual(obj.data, items) def test_string_and_unicode_data(self): DATA = ( ('string', 'Simple string'), ('unicode', u'Simple unicode string'), ) for name, data in DATA: obj = PickleObject.objects.create(name=name, data=data) self.assertEqual(obj.data, data) self.assertEqual(PickleObject.objects.count(), 2) for name, data in DATA: obj = PickleObject.objects.get(name=name) self.assertEqual(obj.data, data)
Надеюсь, что в скором времени эти изменения будут добавлены в django-fields.
4 комментариев:
Прикольно. Это твое? Не хочешь добавить в http://github.com/svetlyak40wt/django-fields/
Спасибо, мне пригодился. А где вы храните описания полей? Просто, на мой взгляд, смешивать их с моделями как-то быдловато.
fields.py? :)
https://github.com/shrubberysoft/django-picklefield - "по-настоящему рабочий PickledObjectField, инфа 100%", у вашего примера некоторые проблемы с не-ASCII символами.
http://bugs.python.org/issue2980 - а вот связанный недобаг.
Отправить комментарий