djangomemcachedpickingdjango-cache

Django cache.set() fails on a class with a GenericForeignKey, What can be the cause?


I have a model with a GenericForeignKey. When calling cache.set(key, trac_obj), it fails. I wonder if the GenericForeignKey is the culprit?

# models.py
class Trac(models.Model):

    user = models.ForeignKey(User, related_name="%(class)s", null=False)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    class Meta:
        unique_together = (('user', 'content_type', 'object_id'),)

# views.py
obj = SomeUserProfile # Django UserProfile (or any other model object)
content_type = ContentType.objects.get_for_model(type(obj))
trac_obj = Trac(user=request.user, content_type=content_type, object_id=obj.pk,
                                   content_object=obj)
trac_obj.save()
cache_key = 'Trac-{0}-{1}-{2}'.format(user.id, content_type.id, obj.id)
cache.set(cache_key, trac_obj)

Here is the error message:

File ".../python2.7/site-packages/memcache.py", line 751, in _val_to_store_info
pickler.dump(val)
File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle instancemethod objects

Solution

  • The error seems to be because one can't directly pickle the results of the .save() method. Try setting the cache before saving the object.

    If you must pickle the .save(), there seem to be ways as elaborated in the answers to this OP: http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods