Generic Api Consumer¶
In DCRF you can create a GenericAsyncAPIConsumer that works much like a GenericAPIView in DRF: For a more indepth look into Rest Like Websocket consumers read this blog post.
We have a set of mixins for the consumer, that add different actions based on the CRUD operations.
ListModelMixin
this mixin adds the actionlist
, allows to retrieve all instances of a model class.RetrieveModelMixin
this mixin adds the actionretrieve
allows to retrieve an object based on the pk sent.PatchModelMixin
this mixin adds the actionpatch
, allows to patch an instance of a model.UpdateModelMixin
this mixin adds the actionupdate
, allows to update a model instance.CreateModelMixin
this mixin adds the actioncreate
, allows to create an instance based on the data sent.DeleteModelMixin
this mixin adds the actiondelete
, allows to delete an instance based on the pk sent.
Example¶
This example shows how to create a basic consumer for the django’s auth user model. We
are going to create a serializer class for it, and mixin with the GenericAsyncAPIConsumer
the action mixins.
# serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
class UserSerilizer(serailizers.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 UserSerilizer
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer
from djangochannelsrestframework.mixins import (
ListModelMixin,
RetrieveModelMixin,
PatchModelMixin,
UpdateModelMixin,
CreateModelMixin,
DeleteModelMixin,
)
class UserConsumer(
ListModelMixin,
RetrieveModelMixin,
PatchModelMixin,
UpdateModelMixin,
CreateModelMixin,
DeleteModelMixin,
GenericAsyncAPIConsumer,
):
queryset = User.objects.all()
serializer_class = UserSerilizer
# 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.
ws.send(JSON.stringify({
action: "list",
request_id: new Date().getTime(),
}))
/* 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'},
{'email': '2@example.com', 'id': 2, 'username': 'test 2'},
{'email': '3@example.com', 'id': 3, 'username': 'test 3'},
]
}
*/
ws.send(JSON.stringify({
action: "retrieve",
request_id: new Date().getTime(),
pk: 2,
}))
/* The return response will be something like this.
{
"action": "retrieve",
"errors": [],
"response_status": 200,
"request_id": 1550050,
"data": {'email': '2@example.com', 'id': 2, 'username': 'test 2'},
}
*/
ws.send(JSON.stringify({
action: "patch",
request_id: new Date().getTime(),
pk: 2,
data: {
email: "edited@example.com",
}
}))
/* The return response will be something like this.
{
"action": "patch",
"errors": [],
"response_status": 200,
"request_id": 1550050,
"data": {'email': 'edited@example.com', 'id': 2, 'username': 'test 2'},
}
*/
ws.send(JSON.stringify({
action: "update",
request_id: new Date().getTime(),
pk: 2,
data: {
username: "user 2",
}
}))
/* The return response will be something like this.
{
"action": "update",
"errors": [],
"response_status": 200,
"request_id": 1550050,
"data": {'email': 'edited@example.com', 'id': 2, 'username': 'user 2'},
}
*/
ws.send(JSON.stringify({
action: "create",
request_id: new Date().getTime(),
data: {
username: "new user 4",
password1: "testpassword123",
password2: "testpassword123",
email: "4@example.com",
}
}))
/* The return response will be something like this.
{
"action": "create",
"errors": [],
"response_status": 201,
"request_id": 1550050,
"data": {'email': '4@example.com', 'id': 4, 'username': 'new user 4'},
}
*/
ws.send(JSON.stringify({
action: "delete",
request_id: new Date().getTime(),
pk: 4,
}))
/* The return response will be something like this.
{
"action": "delete",
"errors": [],
"response_status": 204,
"request_id": 1550050,
"data": null,
}
*/