async_to_sync를 활용하여 channels_layer를 가져오고 group_send를 통하여 알람 기능도 만들 예정이다.
async_to_sync(layer.group_send)(f'alram_{goods.buyer.id}', {'type': 'chat_message', 'response': json.dumps({'response_type': 'alram', 'message': '낙찰됨'})})
팀원 분이 맡아서 하는 부분을 내가 맡게 되면서 기존의 APIView를 ModelViewSet으로 바꾸면서 쿼리를 줄이고 Restfull하게 짜려고 노력해 보았다.
from django.db.models import Prefetch
class IsTrader(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return request.user in [obj.goods.seller, obj.goods.buyer]
class ChatViewSet(ModelViewSet):
"""
리스트 'list' 요청이 오면 채팅방 리스트를 보내줍니다.
특정 방의 요청이 'retrive' 오면 채팅방의 채팅들을 보내줍니다.
"""
permission_classes = [IsTrader,]
def get_permissions(self):
if self.action == 'list':
return [permissions.IsAuthenticated(),]
return super(ChatViewSet, self).get_permissions()
def get_serializer_class(self):
if self.action == 'list':
return TradeInfoSerializer
elif self.action == 'retrive':
return TradeMessageSerializer
else:
return None
def get_serializer_context(self):
# print(self.request.data)
return {
'request': self.request,
'format': self.format_kwarg,
'view': self,
'action' : self.action
}
def get_queryset(self):
print(dir(Goods.objects.first()))
user_id = self.request.user.id
if self.action == 'list':
goods = Goods.objects.filter(status = False, buyer__isnull=False).filter( Q(buyer_id = user_id) | Q(seller_id = user_id)).select_related('seller', 'buyer', 'trade_room').prefetch_related('trade_room__trademessage')
return goods
elif self.action == 'retrive':
return TradeChatRoom.objects.all()
else:
return None
채팅방 리스트 큰 틀 : 내가 구매 혹은 판매 물품의 거래 채팅방을 최근 업데이트 된 날짜로 나열하여 보여준다.
1. 물풀의 객체들에서 상태 값은 False(경매가 끝남), 구매자는 있어야한다.
2. 물품의 구매자 혹은 판매자가 자신이어여야만 한다.
3. 쿼리 수를 줄이기 위해,prefetch 와 select를 사용한다.
4. Goods의 trade_room은 TradeCahtRoom을 외래키로 참조한다(원래는 oto이 맞다).
- annotate를 사용하여 trade_room의 업데이트 날짜 trade_room__updated_at을 가져와
- updated_at의 임의의 컬럼을 만들어 정렬해 준다.
개별 채팅 방 틀 : 요청자의 권한을 파악, 메시지 읽음 처리
1. 특정 Goods 객체의 판매자 혹은 구매자를 판별
2. 해당 객체의 메시지들을 가져와 내가 작성한 것들을 제외한 메시지를 읽음 처리함.
줌