취미삼아 배우는 프로그래밍

Django 3.0 ASGI > 실시간 TodoApp 만들어보기 - 2 본문

파이썬(장고)

Django 3.0 ASGI > 실시간 TodoApp 만들어보기 - 2

Nadure 2019. 12. 28. 11:00

 

주의

정확히 알고 글을 적는게 아닌, 그저 성공 코드를 정리하는 것이니,

주의해주십시오.

 

 

완성품>

대충 이런 느낌으로 되긴 된다..

 

consumer 는 아래와 같다.

# todo.consumer
# consumer.py

from asgiref.sync import async_to_sync, sync_to_async
from channels.generic.websocket import WebsocketConsumer
import json
import asyncio
from channels.db import database_sync_to_async
from .models import ToDoAppModel

class TodoConsumer(WebsocketConsumer):
    def connect(self):
        print('someone connected!')
        #'/ws/todoapp/'
        self.room_group_name = 'todousers'
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        self.accept()

    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        message_type = text_data_json['type']

        if 'id' in text_data_json:
            id = text_data_json['id']
        else:
            id = None

        # self.send(text_data=json.dumps({
        #     'message': message
        # }))

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                # running class below
                'type': message_type,
                'message': message,
                'id':id
            }
        )
    

    # Receive message from room group
    def todo_message(self, event):
        message = event['message']
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))


    def todo_add(self, event):
        print('todo Added!!')
        content = event['message']
        added = ToDoAppModel(main_text=content)
        added.save()

        self.send(text_data=json.dumps({
            'message': content,
            'type':'todo_add',
            'id':added.id,
        }))
    
    def todo_delete(self, event):
        print('todo Delete!!')
        id = event['id']
        try:
            ToDoAppModel.objects.get(id=id).delete()
        except:
            pass
        self.send(text_data=json.dumps({
            'message': '',
            'type':'todo_delete',
            'id':id,
        }))


    

 

그리고 index.html은 아래와 같다.

<!-- todoapp > templates > todoapp > index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

<style>
    .list li{
        /* display: inline; */
        font-size: 40px;
        vertical-align: middle;
    }
    .list input{
        vertical-align: middle;
    }
    .list li .checked{
        text-decoration: line-through;
    }
</style>

</head>
<body>
    
    <div>
        <form method="post" action="">
            {% csrf_token %} 
            {{ form.as_p }}    
            <input type="submit" value="submit" onclick="submitevent(event)">
        </form>


        <ul class="list" id="todo_list">
            {% for content in todo %}
            <li id="li_no_{{ content.id }}">
                <a class="">{{ content.main_text }}</a>
                <!-- <input type="button" value="Edit"> -->
                <input type="button" value="Delete" onclick="todo_delete({{ content.id }})">
            </li>
            <!-- <br> -->
            {% endfor %}
        </ul>
    </div>
    

</body>
<script>
    // 쓰지 않음.
    function href_location(id){
        current = window.location.href
        window.location.href = '/deletetodo/' + id + '/'
    }

    var todoSocket = new WebSocket(
        'ws://' + window.location.host +
        '/ws/todoapp/');

        todoSocket.onmessage = function(e) {
        var data = JSON.parse(e.data);
        console.log(data);
        var content = data.message;
        var id = data.id;
        if(data.type == "todo_add"){
            todo_add(content, id);
        };
        if(data.type == "todo_delete"){
            on_delete(id);
        };
        // console.log('onmessaging : ',data);
        // var message = data['message'];
    };

    todoSocket.onclose = function(e) {
        console.error('Chat socket closed unexpectedly');
    };

    function todo_add(content, id){
        var list = document.getElementById("todo_list");
        var a_li = document.createElement('li');
        var a = document.createTextNode(content);
        var button_text = document.createTextNode('Delete');

        var a_button = document.createElement("button");
        a_button.setAttribute("onclick","todo_delete("+ id +")")
        a_button.appendChild(button_text)
        a_li.setAttribute("id","li_no_"+ id)
        a_li.appendChild(a);
        a_li.appendChild(a_button);
        list.appendChild(a_li);
    };

    function todoSocket_test(content){
        todoSocket.send(JSON.stringify({
            'message': content,
            'type':'todo_add',
            // 'id':content,
        }));
    };

    function submitevent(e){
        e.preventDefault();
        var message = document.getElementById("id_main_text").value;
        todoSocket_test(message);
        document.getElementById("id_main_text").value = "";
    };

    function todo_delete(id){
        todoSocket.send(JSON.stringify({
            'id':id,
            'message': null,
            'type':'todo_delete'
        }));
    };

    function on_delete(id){
        var li = document.getElementById("li_no_"+id);
        li.parentNode.removeChild(li);
    };
</script>
</html>

 

자바스크립트 함수도 생각나는대로 적다보니 정리가 잘 안돼있다. 사실 정리할 줄 모르기도 하다.

그래서 그림으로 설명하자면,

## consumer.py

이렇게 전달받은 text_data 내에서 변수를 선별해, 정의된 함수를 실행시킨다.

변수는 dictionary가 통째로 넘어간다.

 

in HTML

todoSocket 선언시의 약속

 

 

 

코드는 더럽지만,

어떻게 되긴 되니까

이만해야겠다!

Comments