Skip to content

Instantly share code, notes, and snippets.

@alexhayes
Created June 15, 2015 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexhayes/17442e892ede9a2058ff to your computer and use it in GitHub Desktop.
Save alexhayes/17442e892ede9a2058ff to your computer and use it in GitHub Desktop.
Celery Model Serializer

Usage

app = Celery('myapp')

@app.task(serializer='django-model')
def test(x):
    print x
    
obj = MyModel.objects.get(pk=12)
test.delay(obj)
import pickle
from kombu.serialization import register, loads, dumps, unpickle, registry
import copy
from django.db import models
from django.db.models.loading import get_model
from django.utils.encoding import force_str
class SerializedModel(object):
app_label = None
model = None
pk = None
def __init__(self, obj):
self.app_label = obj._meta.app_label
self.model_name = obj._meta.model_name
self.auto_field_value = getattr(obj, obj._meta.auto_field.attname)
def get_model_instance(self):
model_cls = get_model(self.app_label, self.model_name)
auto_field_attname = model_cls._meta.auto_field.attname
auto_field_value = self.auto_field_value
return model_cls.objects.get(**{auto_field_attname: auto_field_value})
def __repr__(self):
return force_str('<%s: %s.%s(%s)>' % (self.__class__.__name__,
self.app_label,
self.model_name,
self.auto_field_value))
def model_decode(data):
_data = unpickle(data)
args = []
args_has_models = False
for obj in _data['args']:
if isinstance(obj, SerializedModel):
args_has_models = True
args.append(obj.get_model_instance())
else:
args.append(obj)
if args_has_models:
_data['args'] = tuple(args)
for kwarg, obj in _data['kwargs']:
if isinstance(obj, SerializedModel):
_data['kwargs'][kwarg] = obj.get_model_instance()
return _data
def model_encode(data):
_data = copy.copy(data)
args = []
args_has_models = False
for obj in _data['args']:
if isinstance(obj, models.Model):
args_has_models = True
args.append(SerializedModel(obj))
else:
args.append(obj)
if args_has_models:
_data['args'] = tuple(args)
for kwarg, obj in _data['kwargs']:
if isinstance(obj, models.Model):
_data['kwargs'][kwarg] = SerializedModel(obj)
return pickle.dumps(_data)
register('django-model', model_encode, model_decode, content_type='application/x-python-serialize', content_encoding='binary')
registry.enable('django-model')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment