Ticket #12057: prevent__init__on_pickle_load.patch

File prevent__init__on_pickle_load.patch, 3.9 KB (added by Michael Thornhill, 15 years ago)

Patch and test cases to prevent init being called when a model instance is loaded from a pickle

  • django/db/models/base.py

     
    346346        """
    347347        data = self.__dict__
    348348        if not self._deferred:
    349             return (self.__class__, (), data)
     349            return super(Model, self).__reduce__()
    350350        defers = []
    351351        pk_val = None
    352352        for field in self._meta.fields:
  • tests/regressiontests/cache/tests.py

     
    1616from django.http import HttpResponse, HttpRequest
    1717from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
    1818from django.utils.hashcompat import md5_constructor
     19from regressiontests.cache.models import Poll, expensive_calculation
    1920
    2021# functions/classes for complex data type tests
    2122def f():
     
    211212        self.cache.set("stuff", stuff)
    212213        self.assertEqual(self.cache.get("stuff"), stuff)
    213214
     215    def test_cache_read_for_model_instance(self):
     216        # Don't want fields with callable as default to be called on cache read
     217        expensive_calculation.num_runs = 0
     218        Poll.objects.all().delete()
     219        my_poll = Poll.objects.create(question="Well?")
     220        self.assertEqual(Poll.objects.count(), 1)
     221        pub_date = my_poll.pub_date
     222        self.cache.set('question', my_poll)
     223        cached_poll = self.cache.get('question')
     224        self.assertEqual(cached_poll.pub_date, pub_date)
     225        # We only want the default expensive calculation run once
     226        self.assertEqual(expensive_calculation.num_runs, 1)
     227       
     228    def test_cache_write_for_model_instance_with_deferred(self):
     229        # Don't want fields with callable as default to be called on cache write
     230        expensive_calculation.num_runs = 0
     231        Poll.objects.all().delete()
     232        my_poll = Poll.objects.create(question="What?")
     233        self.assertEqual(expensive_calculation.num_runs, 1)       
     234        defer_qs = Poll.objects.all().defer('question')
     235        self.assertEqual(defer_qs.count(), 1)
     236        self.cache.set('deferred_queryset', defer_qs)     
     237        # cache set should not re-evaluate default functions   
     238        self.assertEqual(expensive_calculation.num_runs, 1)
     239   
     240    def test_cache_read_for_model_instance_with_deferred(self):
     241        # Don't want fields with callable as default to be called on cache read
     242        expensive_calculation.num_runs = 0
     243        Poll.objects.all().delete()
     244        my_poll = Poll.objects.create(question="What?")
     245        self.assertEqual(expensive_calculation.num_runs, 1)       
     246        defer_qs = Poll.objects.all().defer('question')
     247        self.assertEqual(defer_qs.count(), 1)
     248        self.cache.set('deferred_queryset', defer_qs)
     249        runs_before_cache_read = expensive_calculation.num_runs         
     250        cached_polls = self.cache.get('deferred_queryset')       
     251        # We only want the default expensive calculation run on creation and set
     252        self.assertEqual(expensive_calculation.num_runs, runs_before_cache_read)
     253
    214254    def test_expiration(self):
    215255        # Cache values can be set to expire
    216256        self.cache.set('expire1', 'very quickly', 1)
  • tests/regressiontests/cache/models.py

     
     1from django.db import models
     2from datetime import datetime
     3
     4def expensive_calculation():
     5    expensive_calculation.num_runs += 1   
     6    return datetime.now()
     7
     8class Poll(models.Model):
     9    question = models.CharField(max_length=200)
     10    pub_date = models.DateTimeField('date published', default=expensive_calculation)
Back to Top