您好,我正在使用django开发应用程序。我阅读了所有官方Django Channels文档的文档,但找不到。当用户连接到消费者时,我要将用户添加到组。当更改模型实例时,我将消费者中的信号发送给组中的每个客户端实例,但是我一直都发送信号,所以问题从这里开始,我希望在发送信号时取消前面的消息。我只希望发送给该群组的最新消息消失。我找不到解决方法
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from channels.exceptions import DenyConnection
from main.consumers import AsyncWebsocketConsumer
from auctions.models import Auction, Lot, AuctionBid, AuctionReport, AuctionSaloon, LandLot, HouseLot, Deposit, UserFlag, Participant
from liveauction.serializers import ROAuctionBidSerializer, ROAuctionSerializer, ROHouseLotSerializer, ROLandLotSerializer, ROLotSerializer, ROParticipantSerializer, ROFlagCoverageRangeSerializer, RONormalAuctionSerializer
from django.core.exceptions import ObjectDoesNotExist
import json
import asyncio
class AuctionConsumer(AsyncWebsocketConsumer):
active_auction = None
active_lot = None
permissions = []
channel_groups = []
flag_coverage_ranges = []
async def connect(self):
if self.scope['user']:
user = self.scope['user']
print(self.scope['user'])
if user.is_anonymous:
await self.close()
else:
self.active_auction = await self._get_active_auction()
print(self.active_auction)
if self.active_auction is not None:
print(self.active_auction.get_channel_name())
self.channel_groups.append(self.channel_layer.group_add(
self.active_auction.get_channel_name(), self.channel_name))
asyncio.gather(*self.channel_groups)
self.permissions = await self._get_user_permission(self.scope['user'])
self.flag_coverage_ranges = self.active_auction.flag_coverage_ranges.all()
await self.accept()
else:
await self.close()
async def disconnect(self, code):
asyncio.gather(*self.channel_groups)
await super().disconnect(code)
async def receive(self, text_data):
content = json.loads(text_data)
message_type = content.get('command')
print(message_type)
if await self.has_permission(message_type):
if message_type == 'create.bid':
await self.create_bid(content, True if self.has_permission('create.bid') else False)
elif message_type == 'delete.bid':
await self.delete_bid(content)
elif message_type == 'update.bid':
await self.update_bid(content)
elif message_type == 'change.lot':
await self.change_lot(content)
elif message_type == 'update.auction':
await self.update_auction(content)
elif message_type == 'update.approve':
await self.update_approve(content)
else:
await self.raise_error('Command not found.')
else:
raise DenyConnection('User is not authorized.')
async def create_bid(self, event, auto_next_bid=True):
print('create_bid called')
if self.active_auction.approve_mode:
print("teklif vermek kilitli şuan ?")
return
user_flag = event.get('data').get('flag') if event.get('data').get('flag', False) else await self.get_first_flag()
participant = int(event.get('data').get('participant')) if event.get(
'data').get('participant', False) else int(self.scope['user'].participant.id) if hasattr(self.scope['user'], 'participant') else ''
bid_amount = event.get('data').get('bid') if event.get('data').get(
'bid', False) else self.active_auction.current_lot.next_bid_amount
auto_next_bid = False
if not user_flag or float(bid_amount) < float(self.active_auction.current_lot.next_bid_amount):
print("bura")
pass
if 'admin' not in self.permissions:
getted_current_participant = await self._get_participant(participant)
participant_deposit = getted_current_participant.deposit.filter(
auction__id=self.active_auction.id)
print("teminatı arıyoruz")
if participant_deposit.exists():
if (participant_deposit.deposit - participant_deposit.get_used_flag_deposit_amount()) < self.active_auction.current_lot.minimum_deposit:
print("teminatı yetersiz")
return
else:
print("teminatı yok")
return
last_flag_participant = None
try:
tenor_bids = self.active_auction.current_lot.tenor_bids
bid = tenor_bids
if bid.exists():
bid = bid.last()
last_flag_participant = bid.participant
print(bid)
if last_flag_participant is not None:
print(last_flag_participant)
if getted_current_participant is not None:
print(getted_current_participant)
if getted_current_participant.id == last_flag_participant.id:
print("veremez teklif")
return
except Exception as e:
print(e)
bid_template = {
"flag": user_flag if not isinstance(user_flag, UserFlag) else user_flag.pk,
"bid": bid_amount if auto_next_bid is not True else self.active_auction.current_lot.next_bid_amount,
"user": self.scope['user'].id,
"lot": self.active_auction.current_lot.id,
"participant": participant
}
await self._create_bid(bid_template)
await self.send_everyone_updated_auction()
async def delete_bid(self, event):
...
await self.send_everyone_updated_auction()
async def update_bid(self, event):
...
await self.send_everyone_updated_auction()
async def change_lot(self, event):
...
await self.send_everyone_updated_auction()
async def add_bid_to_lot(self, bid):
...
await self.send_everyone_updated_auction()
async def update_auction(self, event):
print('update_auction called')
auction_data = event.get('data', None)
if auction_data is None:
auction = await self._update_auction(self.active_auction)
if self.has_permission('watch') and not self.has_permission('admin'):
auction_data = RONormalAuctionSerializer(auction).data
else:
auction_data = ROAuctionSerializer(auction).data
await self.send(text_data=json.dumps({
'type': 'update.auction',
'data': auction_data,
'permissions': self.permissions,
'flag_coverage_ranges': [ROFlagCoverageRangeSerializer(i).data for i in self.flag_coverage_ranges],
}))
async def update_approve(self, event):
...
await self.send_everyone_updated_auction()
async def send_everyone_updated_auction(self):
auction = await self._update_auction(self.active_auction)
serialized_data = {
"id": auction.id,
"slug": auction.slug,
"current_lot": {
"slug": auction.current_lot.slug,
"last_bid": None if auction.current_lot.last_bid is None else {
"id": auction.current_lot.last_bid.id,
"slug": auction.current_lot.last_bid.slug,
"flag": auction.current_lot.last_bid.flag if auction.current_lot.last_bid.flag is None else {
"id": auction.current_lot.last_bid.flag if auction.current_lot.last_bid.flag is None else auction.current_lot.last_bid.flag.id,
"slug": auction.current_lot.last_bid.flag.slug,
"flag_number": auction.current_lot.last_bid.flag.flag_number,
},
"participant": auction.current_lot.last_bid.participant if auction.current_lot.last_bid.flag is None else {
"id": auction.current_lot.last_bid.participant.id,
"slug": auction.current_lot.last_bid.participant.slug,
"participant_type": auction.current_lot.last_bid.participant.participant_type,
},
},
"current_bid_amount": auction.current_lot.current_bid_amount,
"next_bid_amount": auction.current_lot.next_bid_amount,
"tenor_status": auction.current_lot.tenor_status,
"type": auction.current_lot.type,
"lot_number": auction.current_lot.lot_number,
"title": auction.current_lot.title,
"description": auction.current_lot.description,
"minimum_deposit": auction.current_lot.minimum_deposit,
"appraised_price": auction.current_lot.appraised_price,
"status": auction.current_lot.status,
"increament_amount": auction.current_lot.increament_amount,
"tenor": auction.current_lot.tenor,
},
"saloons": [],
"title": auction.title,
"description": auction.description,
"status": auction.status,
"approve_mode": auction.approve_mode,
"participants": []
}
await self.channel_layer.group_send(group=self.active_auction.get_channel_name(), message={
'type': 'update.auction',
'data': serialized_data
})
@database_sync_to_async
def _open_approve(self):
...
@database_sync_to_async
def _close_approve(self):
...
@database_sync_to_async
def get_first_flag(self):
...
@database_sync_to_async
def _update_auction(self, auction):
if auction is not None:
serializer = None
try:
auction = Auction.objects.prefetch_related('lots__bids').get(pk=auction.pk)
return auction
except ObjectDoesNotExist:
return None
else:
raise Exception('Have not yet active auction')
@database_sync_to_async
def _delete_bid(self, content):
...
@database_sync_to_async
def _update_bid(self, content):
...
@database_sync_to_async
def _create_bid(self, content):
...
@database_sync_to_async
def _get_participant(self, participant_id):
...
@database_sync_to_async
def _add_bid_to_lot(self, content):
...
@database_sync_to_async
def _get_user_permission(self, user):
...
@database_sync_to_async
def _get_active_auction(self):
...
# TODO: Müzayededeki en son aktif Lot getirelecek
@database_sync_to_async
def _get_active_lot(self):
...
@database_sync_to_async
def _change_lot(self, content):
...
@database_sync_to_async
def has_permission(self, permission):
...