From 5d2354c71b6094e2fa4eab7693f33d5af6436d73 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Mon, 18 Jul 2016 14:57:19 -0400 Subject: [PATCH] Provide default serializers for the JSON one --- channels/binding/base.py | 12 +++++++++--- channels/binding/websockets.py | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/channels/binding/base.py b/channels/binding/base.py index d2b9728..0afbdf1 100644 --- a/channels/binding/base.py +++ b/channels/binding/base.py @@ -161,9 +161,9 @@ class Binding(object): if action == "create": self.create(data) elif action == "update": - self.update(self.model.objects.get(pk=pk), data) + self.update(pk, data) elif action == "delete": - self.model.objects.filter(pk=pk).delete() + self.delete(pk) else: raise ValueError("Bad action %r" % action) @@ -173,8 +173,14 @@ class Binding(object): """ raise NotImplementedError() - def update(self, instance, data): + def update(self, pk, data): """ Updates the model with the data. """ raise NotImplementedError() + + def delete(self, pk): + """ + Deletes the model instance. + """ + self.model.objects.filter(pk=pk).delete() diff --git a/channels/binding/websockets.py b/channels/binding/websockets.py index d664d27..27f6563 100644 --- a/channels/binding/websockets.py +++ b/channels/binding/websockets.py @@ -1,5 +1,7 @@ import json +from django.core import serializers + from .base import Binding from ..generic.websockets import JsonWebsocketConsumer @@ -10,10 +12,12 @@ class WebsocketBinding(Binding): To implement outbound, implement: - group_names, which returns a list of group names to send to - - serialize_data, which returns JSON-safe data from a model instance To implement inbound, implement: - has_permission, which says if the user can do the action on an instance + + Optionally also implement: + - serialize_data, which returns JSON-safe data from a model instance - create, which takes incoming data and makes a model instance - update, which takes incoming data and a model instance and applies one to the other """ @@ -41,7 +45,8 @@ class WebsocketBinding(Binding): """ Serializes model data into JSON-compatible types. """ - raise NotImplementedError() + data = serializers.serialize('json', [instance]) + return json.loads(data)[0]['fields'] # Inbound @@ -52,6 +57,31 @@ class WebsocketBinding(Binding): data = content.get('data', None) return action, pk, data + def _hydrate(self, pk, data): + """ + Given a raw "data" section of an incoming message, returns a + DeserializedObject. + """ + s_data = [ + { + "pk": pk, + "model": self.model_label, + "fields": data, + } + ] + # TODO: Avoid the JSON roundtrip by using encoder directly? + return list(serializers.deserialize("json", json.dumps(s_data)))[0] + + def create(self, data): + self._hydrate(None, data).save() + + def update(self, pk, data): + instance = self.model.objects.get(pk=pk) + hydrated = self._hydrate(pk, data) + for name in data.keys(): + setattr(instance, name, getattr(hydrated.object, name)) + instance.save() + class WebsocketBindingDemultiplexer(JsonWebsocketConsumer): """