Search code examples
pythondjangowebsocketdjango-channels

Querying Models in Django Channels


I have been trying to query my database from my consumers.py but seems the query isn't working as I keep getting this error which shows that query wasn't sent. Here is the error :

  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/utils.py", line 51, in await_many_dispatch
    await dispatch(result)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/consumer.py", line 73, in dispatch
    await handler(message)
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/order/lib/python3.6/site-packages/channels/generic/websocket.py", line 196, in websocket_receive
    await self.receive(text_data=message["text"])
  File "/Users/MichaelAjanaku/Desktop/Kitchen-Order/Kitchen_Order/Order_app/consumers.py", line 52, in receive
    info = order_data_json['info']
KeyError: 'info'
WebSocket DISCONNECT /ws/orders/ [127.0.0.1:53953]

Here is my consumers.py set up:

import json
from .models import Order
from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer

class WSConsumer(AsyncWebsocketConsumer):
    
    @database_sync_to_async
    def _get_order_info(self, number):
        return Order.objects.get(order_number = number)


  
    async def connect(self):
        self.groupname = 'kitchen'
        await self.channel_layer.group_add(
                    self.groupname,
                    self.channel_name,
                )      
        await self.accept()

   
    async def disconnect(self, code):
        await self.channel_layer.group_discard(
            self.groupname,
            self.channel_name,
        )
        await super().disconnect(code)



    async def take_order(self, event):
        number = event['number']
        details = event['details']
        info = await self._get_order_info(number)
 

        await self.send(text_data=json.dumps({   
    
                'number' : number,
                'details' : details,
                'info' : info,
                  
                 }))

    async def receive(self, text_data):
        order_data_json = json.loads(text_data)
        number = order_data_json['number']
        details = order_data_json['details']
        info = order_data_json['info']
   

        await self.channel_layer.group_send(
            self.groupname,
            {   
                'type': 'take_order',
                'number' : number,
                'details' : details,
                'info' : info,
            
            }
        )

   

Websocket code on the front end:

document.querySelector('#submit').onclick = function(e) {
        const numberInputDom = document.querySelector('#id_order_number');
        const detailsInputDom = document.querySelector('#id_order_details');
        const number = numberInputDom.value;
        const details = detailsInputDom.value;
        orderSocket.send(JSON.stringify({
            'number': number,
            'details' : details,
        }));
        console.log('data sent')
       
    }; 

So basically I am sending data from a form in the template, then I want to query that data against my database, to get the full info of the data, but sadly, my querying isn't working.

I have tried everything I know but to no avail.

What might be wrong or what am I missing? Thanks


Solution

  • I don't think this is a db query-related issue, but an issue related to the data that your WS is receiving in the receive method. You are sending number and details in the message, but where is the info field in your JSON object in the js code?

    KeyError: 'info' in the receive method means that you are attempting to access a key in your order_data_json dictionary that is not present. Try to add info to the JSON on the frontend, send the message and give it another shot!