2017-10-06 3 views
1

고객이 주문을하고 다른 상점에서 해당 주문에 대한 가격을 제공 할 수있는 경매 유형 시스템을 개발하려고합니다.채널 소비자 클래스에서 django 신호 사용

이 시스템의 흥미로운 부분은 주문이 처음 생성 될 때 사용 가능한 상점이 해당 제안을하기 위해 60 초가 소요된다는 것입니다. 첫 번째 점포가 자신의 제안을하면 "경매"는 이제 다른 점포가 자신의 제안을 할 때까지 20 초 밖에 걸리지 않습니다. 그들이 더 적은 할당 시간에 다른 제안을하면,이 20 초가 새로 고쳐집니다. 제안 된 시간은 주어진 초기 60 초를 초과 할 수 없습니다.

class Order(models.Model): 
    customer = models.ForeignKey(Customer) 
    create_time = models.DateTimeField(auto_now_add=True) 
    update_time = models.DateTimeField(auto_now_add=True) 
    total = models.FloatField(default=0) 
    status = models.IntegerField(default=0) 
    delivery_address = models.ForeignKey(DeliveryAddress) 
    store = models.ForeignKey(Store, null=True, blank=True, related_name='orders', on_delete=models.CASCADE) 
    credit_card = models.ForeignKey(CreditCard, null=True, blank=True, related_name='orders') 

class OrderOffer(models.Model): 
    store = models.ForeignKey(Store, related_name="offers", on_delete=models.CASCADE) 
    order = models.ForeignKey(Order, related_name="offers", on_delete=models.CASCADE) 
    create_time = models.DateTimeField(auto_now_add=True) 

는 이러한 요구 사항 외에, 나는 또한 새로운 제안은 실시간으로 도착했을 때 클라이언트를 업데이트 할. 이를 위해 웹 소켓 구현 인 django-channels을 사용하고 있습니다. 나는 성공적으로 내 클라이언트와 서버 사이의 웹 소켓 통신 채널을 확립 할 수 있었다

from channels.generic.websockets import WebsocketConsumer 
from threading import Timer 
from api.models import Order, OrderOffer 
from django.db.models.signals import post_save 
from django.dispatch import receiver 

class OrderConsumer(WebsocketConsumer): 

    def connect(self, message, **kwargs): 
     """ 
     Initialize objects here. 
     """ 
     order_id = int(kwargs['order_id']) 
     self.order = Order.objects.get(id=order_id) 
     self.timer = Timer(60, self.sendDone) 
     self.timer.start() 
     self.message.reply_channel.send({"accept": True}) 

    def sendDone(self): 
     self.send(text="Done") 

    # How do I bind self to onOffer? 
    @receiver(post_save, sender=OrderOffer) 
    def onOffer(self, sender, **kwargs): 
     self.send(text="Offer received!") 
     if (len(self.offers) == 0): 
      self.offerTimer = Timer(20, self.sendDone) 
      self.offers = [kwargs['instance'],] 
     else: 
      self.offerTimer = Timer(20, self.sendDone) 

     self.offers.append(kwargs['instance']) 


    def receive(self, text=None, bytes=None, **kwargs): 
     # Echo 
     self.send(text=text, bytes=bytes) 

    def disconnect(self, message, **kwargs): 
     """ 
     Perform necessary disconnect operations. 
     """ 
     pass 

:

나는 다음과 같은 consumers.py 파일이 있습니다. 메시지 전송을 테스트 한 결과 모든 것이 정상적으로 보입니다. 이제 새로운 OrderOffer의 생성을 감지하고 클라이언트에게 알림을 보내려고합니다. 이를 위해, 신호 장식자가이 매개 변수를 전송하지 않기 때문에 self.send을 사용하려면 self 변수에 액세스해야합니다. 불가능합니다. 내가 자기와 onOffer를 선언하여 강제로 시도했다, 그러나 나는 다음과 같은 오류 얻을 : context = self : 어떻게 든 키워드 인수에 액세스 할 수있는 경우

TypeError: onOffer() missing 1 required positional argument: 'self'

하면, 세트 신호 즉, 내가 아마도 뭔가를 할 수 있습니다를 .

본인의 원래 문제에 대한 도움이나 대체 솔루션을 제공해 주셔서 감사합니다. 저장 방법 모델에서,이 경우에는 - - 당신이 "외부"에서 소비자에게 얘기하고 싶지 않으면

답변

0

당신은 그것을 얘기 채널 층을 사용해야합니다 : http://channels.readthedocs.io/en/latest/topics/channel_layers.html

기본적으로 당신 ' 필요 것이다 :

  • 시작시 그룹에 소비자를 추가 지정 type로 새로운 OrderOffer있을 때마다
  • 이 그룹에 메시지를 보내기 (아마 수주 ID 기준) - 예를 들어, {"type": "order.new_offer", "order_offer_id": 45}
  • 즉이 처리하는 소비자에 대한 핸들러를 정의 -이 경우에는 그 핸들러는 다음 소켓을 얘기 self.send을 사용할 수 있습니다에서 def order_new_offer(self, event):
  • 수 (데이터베이스 경우를 조회 할 수 있도록이, 유형 이름과 일치 이벤트 메시지에 넣지 않은 클라이언트에게 보낼 추가 정보가 필요함).
당신은 MultiChat 예제 프로젝트에서이의 변형을 볼 수 있습니다

: https://github.com/andrewgodwin/channels-examples/tree/master/multichat