바뀜

편집 요약 없음
304번째 줄: 304번째 줄:  
</syntaxhighlight>
 
</syntaxhighlight>
 
|}
 
|}
 +
== 개요 ==
 +
레디스 서버를 이용한 실시간 채팅 구현
 +
===사전설정===
 +
{| class="wikitable"
 +
!과정
 +
!설명
 +
!방법
 +
|-
 +
| 서버 설치
 +
|
 +
|apt-get install redis-server
 +
|-
 +
|서버 테스트
 +
|서버가 잘 설치되었는지 테스트.
 +
서버 구동에 대한 메시지가 뜬다.
 +
|redis-server
 +
|-
 +
|채널 라이브러리 설치
 +
|장고에서 사용할 채널 라이브러리를 설치한다.
 +
|pip install -U channels
 +
|-
 +
|연동 라이브러리 설치
 +
|서버와 채널을 연동할 라이브러리를 설치한다.
 +
|pip install channels_redis
 +
|-
 +
|앱을 만든다.
 +
|
 +
|django-admin startapp chat
 +
|-
 +
|앱 등록
 +
|settings.py에 추가.
 +
|INSTALLED_APPS 가장 위에 'channels', 'chat'을 맨 위에 추가해준다.
 +
다른 서드파티 앱과 충돌할 수 있어 가장 처음에 둔다.
 +
|-
 +
|세팅
 +
|settings.py 안에 추가.
 +
|<syntaxhighlight lang="python">
 +
ASGI_APPLICATION = 'config.routhing.application'
 +
 +
CHANNEL_LAYERS = {
 +
    'default':{
 +
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
 +
        'CONFIG': {
 +
            "hosts": [('127.0.0.1', 6379)],
 +
        }
 +
    }
 +
}
 +
 +
os.environ["DJANGO_ALLOW_ASYNC_UNDAFE"] = "true"
 +
</syntaxhighlight>을 추가해준다.(대강 스테틱 설정 아래면 적당)
 +
|}
 +
==모델작성==
 +
chat 앱의 models.py 작성<syntaxhighlight lang="python">
 +
from django.db import models
 +
from django.conf import settings
 +
 +
class Room(models.Model):
 +
    room_name = models.CharField(max_length=100, blank=True)
 +
    users = models.ManyToManyfield(
 +
        settings.AUTH_USER_MODEL,  # 유저모델과 연결한다.
 +
        blank=True,
 +
        related_name = 'rooms')  # 룸이라는 인덱스 지정.
 +
   
 +
    def __str__(self):
 +
        return self.room_name
 +
       
 +
class Message(models.Model):
 +
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
 +
    room = models.ForeignKey(Room, related_name='messages', default=1, on_delete=models.CASCADE)
 +
    content = models.TextField(blank=True)
 +
    created_at = models.DateTimeField(auto_now_add=True)
 +
   
 +
    def __str__(self):
 +
        return self.content
 +
</syntaxhighlight>chat앱의 admin.py 작성<syntaxhighlight lang="python">
 +
from django.contrib import admin
 +
from .models import Room, Message
 +
 +
@admin.register(Room)
 +
class RoomAdmin(admin.ModelAdmin):
 +
    list_display = ['id', 'room_name']
 +
    list_display_links = ['room_name']
 +
   
 +
@admin.register(Room)
 +
class MessageAdmin(admin.ModelAdmin):
 +
    list_display = ['user', 'room', 'content', 'created_at']
 +
    list_display_links = ['user', 'room', 'content', 'created_at']
 +
</syntaxhighlight>대화모델 작성(보통 친구모델 등에 작성된다.)(근데 그냥 chat 앱 안에 작성하면 안되나...?)<syntaxhighlight lang="python">
 +
...
 +
from .chat.models import Room, Message
 +
 +
class chat_connection(models.Model):
 +
    target = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE)  # 상대방
 +
    room = models.ForeignKey(Room, blank=True, on_delete=models.SET_NULL, null=True)  # null옵션이 있어야 하나..? 없어도 될듯, 강의에선 친구모델 위에 더하느라 붙인듯.
 +
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE)  # 나
 +
    created_at = models.DateField(auto_now_add=True)
 +
   
 +
    def __str__(self):
 +
        return self.user.username + "채팅"  # 사용자명을 반환한다.
 +
</syntaxhighlight>
 +
==뷰 작성==
 +
<syntaxhighlight lang="python">
 +
from django.shortcuts import render, get_object_or_404
 +
forom django.contrib.auth import get_user_model
 +
from chat.models import *
 +
import logging
 +
 +
def start_chat(request):
 +
    from_user =  # 본인의 유저모델 가져오기
 +
    to_user = 유저모델.objects.get(pk=target_request_id)  # 상대의 유저모델 가져오기(이름이나 pk로 불러오게 하면 될듯)
 +
   
 +
    room_name = "{},{}".format(from_user.username, to_user.username)
 +
    room = Room.objects.create(room_name=room_name)  # 룸을 만든다.
 +
   
 +
def chat_list(request):
 +
    user = request.user
 +
    user_profile = user.user_profile
 +
    friends = user.friends.all()  # 모든 친구 불러오기...(채팅자 목록이라고 보면 됨.)
 +
   
 +
    context = {'user_profile': user_profile,
 +
                'friends':friends,
 +
    }
 +
   
 +
    return render(request, 'chat/chat_list.html', context)
 +
   
 +
def room(request, room_id):
 +
    user = request.user
 +
    user_profile = user.profile
 +
    friends = user.friends.all()  # 모든 친구 불러오기...(채팅자 목록이라고 보면 됨.)
 +
   
 +
    room = Room.objects.get(pk=room_id)  # 룸 모델에서 해당 pk에 맞는 룸 불러오기
 +
    friends_uer = room.users.all().exclude(pk=user.id).first()
 +
   
 +
    context = {'current_user': user,
 +
        'user_profile': user_profile,
 +
        'friends':friends,
 +
        'room':room,
 +
        'friends_user': friends_user,
 +
    }
 +
   
 +
    return render(request, 'chat/room.html', context)
 +
 +
   
 +
</syntaxhighlight>
 +
==url 작성==
 +
config의 url을 넘김 처리하고..
 +
 +
chat앱 안의 urls.py를 작성한다.<syntaxhighlight lang="python">
 +
from .views import *
 +
 +
app_name= 'chat'
 +
 +
urlpatterns = [
 +
    path('', chat_list, name='chat_list'),
 +
    paht('<str:room_id', room, name='room'),
 +
]
 +
</syntaxhighlight>
 +
==탬플릿 작성 ==
 +
chat 앱 안의 templates 폴더를 만든 다음 넣는다.<syntaxhighlight lang="html+django">
 +
<!--확장코드-->
 +
 +
<!--들어가야 할 것들-->
 +
<script src="{% static 'js/messenger.js' %}"></script>
 +
 +
<div id="user_list">
 +
    {% for friend in friends %}
 +
        {% if friend.room %}
 +
        <li name="{{ friend.room.id }}"><a href="/chat/{{ friend.room.id }}/"
 +
        <div>{{ friend.user }}</div>
 +
</div>
 +
 +
<div id="time_line">
 +
    <div id="main_section">
 +
        <div id="feed">
 +
            <div id="text_field">
 +
                <input type="text" id="txt">
 +
                <button type="submit" id="btn">전송</button>
 +
            </div>
 +
        </div>
 +
    </div>
 +
</div>
 +
</syntaxhighlight>
 
[[분류:장고 기능구현(중급)]]
 
[[분류:장고 기능구현(중급)]]