Commit 2faa3acb authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixed #13328 -- Added a __getstate__/__setstate__ pair to fields so that...

Fixed #13328 -- Added a __getstate__/__setstate__ pair to fields so that callable default values aren't pickled. Thanks to bkonkle for the report, and Vitaly Babiy for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12977 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent d9aaad4e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ answer newbie questions, and generally made Django that much better:
    David Avsajanishvili <avsd05@gmail.com>
    Mike Axiak <axiak@mit.edu>
    Niran Babalola <niran@niran.org>
    Vitaly Babiy <vbabiy86@gmail.com>
    Morten Bagai <m@bagai.com>
    Jeff Balogh <jbalogh@mozilla.com>
    Mikaël Barbero <mikael.barbero nospam at nospam free.fr>
+14 −0
Original line number Diff line number Diff line
@@ -132,6 +132,19 @@ class Field(object):
        memodict[id(self)] = obj
        return obj

    def __getstate__(self):
        "Don't try to pickle a callable default value"
        obj_dict = self.__dict__.copy()
        del obj_dict['default']
        return obj_dict

    def __setstate__(self, data):
        "When unpickling, restore the callable default"
        self.__dict__.update(data)

        # Restore the default
        self.default = self.model._meta.get_field_by_name(self.name)[0].default

    def to_python(self, value):
        """
        Converts the input value into the expected Python data type, raising
@@ -233,6 +246,7 @@ class Field(object):

    def contribute_to_class(self, cls, name):
        self.set_attributes_from_name(name)
        self.model = cls
        cls._meta.add_field(self)
        if self.choices:
            setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self))
+6 −3
Original line number Diff line number Diff line
@@ -10,7 +10,10 @@ class OrderWrt(fields.IntegerField):
    A proxy for the _order database field that is used when
    Meta.order_with_respect_to is specified.
    """
    name = '_order'
    attname = '_order'
    column = '_order'

    def __init__(self, model, *args, **kwargs):
        super(OrderWrt, self).__init__(*args, **kwargs)
        self.model = model
        self.attname = '_order'
        self.column = '_order'
        self.name = '_order'
+2 −2
Original line number Diff line number Diff line
@@ -104,11 +104,11 @@ class Options(object):
            self.db_table = "%s_%s" % (self.app_label, self.module_name)
            self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())


    def _prepare(self, model):
        if self.order_with_respect_to:
            self.order_with_respect_to = self.get_field(self.order_with_respect_to)
            self.ordering = ('_order',)
            self._order = OrderWrt(model)
        else:
            self.order_with_respect_to = None

@@ -331,7 +331,7 @@ class Options(object):
        for f, model in self.get_fields_with_model():
            cache[f.name] = (f, model, True, False)
        if self.order_with_respect_to:
            cache['_order'] = OrderWrt(), None, True, False
            cache['_order'] = self._order, None, True, False
        if app_cache_ready():
            self._name_map = cache
        return cache
+12 −0
Original line number Diff line number Diff line
import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _

class Numbers(object):

    @classmethod
    def get_number(self):
        return 2

class Group(models.Model):
    name = models.CharField(_('name'), max_length=100)

class Event(models.Model):
    group = models.ForeignKey(Group)

class Happening(models.Model):
    when = models.DateTimeField(blank=True, default=datetime.datetime.now)
    name = models.CharField(blank=True, max_length=100, default=lambda:"test")
    number = models.IntegerField(blank=True, default=Numbers.get_number)
Loading