2017-10-06 42 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實現WebSockets。

我有以下consumers.py文件:

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 

我已經成功地得以我的客戶端和服務器之間建立WebSocket的通信信道。我測試過發送消息,一切似乎都沒問題。現在我想檢測新的OrderOffer的創建,並向客戶端發送通知。爲此,我需要訪問self變量,使用self.send,這是不可能的,因爲信號修飾器不發送此參數。我試着用自我聲明onOffer迫使它,但我得到了以下錯誤:

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

如果我能以某種方式使用關鍵字參數,即信號臺,我可能會做這樣的事情: context = self

我將不勝感激任何幫助,甚至對我原來的問題的替代解決方案。

回答

0

如果你想談消費者從「外」 - 在這種情況下,從一個模型保存方法 - 你需要使用一個通道層去跟它:http://channels.readthedocs.io/en/latest/topics/channel_layers.html

從本質上講,你」會需要:

  • 加入消費者一組啓動(可能是基於其訂單ID)
  • 將消息發送到集團每當有一個新的OrderOffer使用自定義type - 例如: {"type": "order.new_offer", "order_offer_id": 45}
  • 定義對消費者的處理程序來處理這一點 - 它匹配的類型名稱,所以在這種情況下,將def order_new_offer(self, event):
  • 在該處理程序,那麼你可以使用self.send談下來的插座(和查詢數據庫,如果您需要額外的信息發送給您未放入事件消息的客戶端)。

你可以看到這方面的一個變型的MultiChat示例項目:https://github.com/andrewgodwin/channels-examples/tree/master/multichat

相關問題