Observer model instance
This mixin consumer lets you subscribe to all changes of a specific instance and
gives you access to the retrieve
action.
# serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["id", "username", "email", "password"]
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
email=validated_data['email'],
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
# consumers.py
from django.contrib.auth.models import User
from .serializers import UserSerializer
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer
from djangochannelsrestframework.observer.generics import ObserverModelInstanceMixin
class UserConsumer(ObserverModelInstanceMixin, GenericAsyncAPIConsumer):
queryset = User.objects.all()
serializer_class = UserSerializer
# routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"^ws/$", consumers.UserConsumer.as_asgi()),
]
How to use it
First, we will create the web socket instance in javascript
.
const ws = new WebSocket("ws://localhost:8000/ws/")
ws.onmessage = function(e){
console.log(e)
}
Note
We must have a few users in our database for testing, if not, create them.
Retrieve action.
ws.send(JSON.stringify({
action: "retrieve",
request_id: new Date().getTime(),
pk: 1,
}))
/* The return response will be something like this.
{
"action": "list",
"errors": [],
"response_status": 200,
"request_id": 1550050,
"data": {'email': '1@example.com', 'id': 1, 'username': 'test 1'},
}
*/
Subscription
Subscribe to a specific instance.
ws.send(JSON.stringify({
action: "retrieve",
request_id: new Date().getTime(),
pk: 1,
}))
/* After subscribing the response will be something like this.
{
"action": "subscribe_instance",
"errors": [],
"response_status": 201,
"request_id": 1550050,
"data": null,
}
*/
Changing the model instance from the shell will fire the subscription event.
>>> from django.contrib.auth.models import User
>>> user = User.objects.get(pk=1)
>>> user.username = "edited user name"
>>> user.save()
After saving the model instance in the console, we will see the subscription message.
{
action: "update",
errors: [],
response_status: 200,
request_id: 1550050,
data: {email: '1@example.com', id: 1, username: 'edited user name'},
}
Todo
More detailed example.