django - How to access/create a proper Request object for DRF Serializer? -
i have created rest api using drf, , works enough. frontend simple page allows data viewed , updated. trying add more interactivity site using websockets django-channels
. channels system simple use , works nicely.
however issue facing trying combine of moving pieces work together. idea initial page refresh comes through rest api, , subsequent updates automagically come through websocket after every update (with of post_save
signal). have nice drf serializers models, alas not work without request object (for instance hyperlinkedidentityfield
):
assertionerror: `hyperlinkedidentityfield` requires request in serializer context. add `context={'request': request}` when instantiating serializer.
so question is, how somehow create/fake proper request object serializers want when trying serialize model in signal handler?
edit
the more think this, more obvious becomes not right way go. there no way craft single, generic request
object serializers, since model updates trigger them can come source. not make sense try creating one. think have separate "base" serializers (without hyperlinks) , use send updates clients. since hyperlinks won't ever change, think proper way go.
in case might interested, here how solved issue. main bits , pieces of code below.
first simple model (myapp/models.py):
from django.db import models class mymodel(models.model): name = models.textfield()
then serializers (myapp/serializers.py):
from rest_framework import serializers mymodelserializer(serializers.hyperlinkedmodelserializer): class meta: model = mymodel fields = ('url', 'id', 'name') extra_kwargs = {'url': {'view_name': 'mymodel-detail'}} mymodelbaseserializer(serializers.modelserializer): class meta: model = mymodel fields = ('id', 'name')
and views (myapp/views.py):
from rest_framework import viewsets myapp.models import mymodel myapp.serializers import mymodelserializer class mymodelviewset(viewsets.modelviewset): queryset = mymodel.objects.all() serializer_class = mymodelserializer
and channels message consumer (myapp/consumers.py):
import json django.db.models.signals import pre_save django.dispatch import receiver channels import group myapp.models import mymodel myapp.serializers import mymodelbaseserializer def ws_add(message): message.reply_channel.send({"accept": true}) group("mymodel").add(message.reply_channel) def ws_disconnect(message): group("mymodel").discard(message.reply_channel) @receiver(post_save, sender=mymodel) def mymodel_handler(sender, instance, **kwargs): group("mymodel").send({ "text": json.dumps({ "model": "mymodel", "data": mymodelbaseserializer(instance).data }) })
i have omitted things urls.py , routing.py not relevant issue. can seen, regular view uses normal mymodelserializer
includes url, , update handler mymodelbaseserializer
has fields not dependent on request
object.
Comments
Post a Comment