Base observer

class djangochannelsrestframework.observer.base_observer.BaseObserver(func, partition: str = '*')[source]

Base observer class

serializer(func)[source]

Adds a Serializer to the model observer return.

Note

This is meant to use as a decorator.

Examples

TODO path to examples?

# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

class Comment(models.Model):
    text = models.TextField()
    user = models.ForeignKey(User, related_name="comments", on_delete=models.CASCADE)
    date = models.DatetimeField(auto_now_add=True)
# serializers.py
from rest_framework import serializers
from .models import User, Comment

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "username", "email"]

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ["id", "text", "user"]
# consumers.py

from djangochannelsrestframework.consumers import GenericAsyncAPIConsumer
from djangochannelsrestframework.observer import model_observer
from djangochannelsrestframework.decorators import action

from .serializers import UserSerializer, CommentSerializer
from .models import User, Comment

class MyConsumer(GenericAsyncAPIConsumer):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @model_observer(Comments)
    async def comment_activity(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @comment_activity.serializer
    def comment_activity(self, instance: Comment, action, **kwargs):
        return CommentSerializer(instance).data

    @action()
    async def subscribe_to_comment_activity(self, **kwargs):
        await self.comment_activity.subscribe()

Now we will have a websocket client in javascript listening to the messages, after subscribing to the comment activity. This codeblock can be used it in the browser console.

const ws = new WebSocket("ws://localhost:8000/ws/my-consumer/")
const ws.onopen = function(){
    ws.send(JSON.stringify({
        action: "subscribe_to_comment_activity",
        request_id: new Date().getTime(),
    }))
}
const ws.onmessage = function(e){
    console.log(e)
}

In the IPython shell we will create some comments for differnt users and in the browser console we will se the log.

Note

At this point we should have some users in our database, otherwise create them

>>> from my_app.models import User, Comment
>>> user_1 = User.objects.get(pk=1)
>>> user_2 = User.objects.get(pk=2)
>>> Comment.objects.create(text="user 1 creates a new comment", user=user_1)

In the consol log we will se something like this:

{
    action: "subscribe_to_comment_activity",
    errors: [],
    response_status: 200,
    request_id: 15606042,
    data: {
        id: 1,
        text: "user 1 creates a new comment",
        user: 1,
    },
}

Now we will create a comment with the user 2.

>>> Comment.objects.create(text="user 2 creates a second comment", user=user_2)

In the consol log we will se something like this:

{
    action: "subscribe_to_comment_activity",
    errors: [],
    response_status: 200,
    request_id: 15606042,
    data: {
        id: 2,
        text: "user 2 creates a second comment",
        user: 2,
    },
}

As you can see in this example, we are subscribe to ALL ACTIVITY of the comment model.