2015-02-24 00:43:46 +00:00
|
|
|
"""Django DDP utils for DDP messaging."""
|
2015-04-27 12:30:52 +00:00
|
|
|
from copy import deepcopy
|
2015-05-21 02:51:43 +00:00
|
|
|
from dddp import THREAD_LOCAL as this, REMOVED
|
2015-06-12 13:08:27 +00:00
|
|
|
try:
|
|
|
|
|
from django.db.models.expressions import ExpressionNode
|
|
|
|
|
except AttributeError:
|
|
|
|
|
ExpressionNode = None
|
2015-04-22 23:41:49 +00:00
|
|
|
|
2015-02-24 00:43:46 +00:00
|
|
|
|
|
|
|
|
def obj_change_as_msg(obj, msg):
|
|
|
|
|
"""Generate a DDP msg for obj with specified msg type."""
|
2015-06-12 13:08:27 +00:00
|
|
|
if ExpressionNode is None:
|
|
|
|
|
exps = False
|
|
|
|
|
else:
|
|
|
|
|
# check for F expressions
|
|
|
|
|
exps = [
|
|
|
|
|
name for name, val in vars(obj).items()
|
|
|
|
|
if isinstance(val, ExpressionNode)
|
|
|
|
|
]
|
2015-04-27 12:30:52 +00:00
|
|
|
if exps:
|
|
|
|
|
# clone and update obj with values but only for the expression fields
|
|
|
|
|
obj = deepcopy(obj)
|
|
|
|
|
# Django 1.8 makes obj._meta public --> pylint: disable=W0212
|
|
|
|
|
for name, val in obj._meta.model.objects.values(*exps).get(pk=obj.pk):
|
|
|
|
|
setattr(obj, name, val)
|
|
|
|
|
|
|
|
|
|
# run serialization now that all fields are "concrete" (not F expressions)
|
2015-04-27 00:29:00 +00:00
|
|
|
serializer = this.serializer
|
2015-04-22 23:41:49 +00:00
|
|
|
data = serializer.serialize([obj])[0]
|
2015-04-27 00:29:00 +00:00
|
|
|
|
|
|
|
|
# collection name is <app>.<model>
|
2015-02-24 00:43:46 +00:00
|
|
|
name = data['model']
|
|
|
|
|
|
|
|
|
|
# cast ID as string
|
|
|
|
|
if not isinstance(data['pk'], basestring):
|
|
|
|
|
data['pk'] = '%d' % data['pk']
|
|
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
'msg': msg,
|
|
|
|
|
'collection': name,
|
|
|
|
|
'id': data['pk'],
|
|
|
|
|
}
|
2015-05-21 02:51:43 +00:00
|
|
|
if msg != REMOVED:
|
2015-02-24 00:43:46 +00:00
|
|
|
payload['fields'] = data['fields']
|
|
|
|
|
|
|
|
|
|
return (name, payload)
|