changes
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
141
app/consumers.py
141
app/consumers.py
@@ -54,77 +54,86 @@ class DataConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
self.subscribed_groups.add(group_name)
|
self.subscribed_groups.add(group_name)
|
||||||
|
|
||||||
async def realtime_update(self, event):
|
async def realtime_update(self, event):
|
||||||
# Move imports inside the method to prevent AppRegistryNotReady error on startup
|
# Bước gỡ lỗi cuối cùng: xác nhận phương thức này được gọi và bắt bất kỳ lỗi nào
|
||||||
from django.db.models import Q
|
print(f"--- CONSUMER: realtime_update invoked for event name: {event['payload']['name']} ---")
|
||||||
from .views import get_serializer
|
try:
|
||||||
|
# Move imports inside the method to prevent AppRegistryNotReady error on startup
|
||||||
|
from django.db.models import Q
|
||||||
|
from .views import get_serializer
|
||||||
|
|
||||||
payload = event["payload"]
|
payload = event["payload"]
|
||||||
change_type = payload.get("change_type")
|
change_type = payload.get("change_type")
|
||||||
record_id = payload["record"].get("id")
|
record_id = payload["record"].get("id")
|
||||||
|
|
||||||
if not record_id or not change_type:
|
if not record_id or not change_type:
|
||||||
return
|
return
|
||||||
|
|
||||||
model_name_lower = payload["name"]
|
model_name_lower = payload["name"]
|
||||||
model_name_capitalized = model_name_lower.capitalize()
|
# Chuyển đổi snake_case (từ signal) thành PascalCase với dấu gạch dưới (được sử dụng trong subscription)
|
||||||
|
# Ví dụ: 'product_note' -> 'Product_Note'
|
||||||
|
model_name_pascal_case = '_'.join(word.capitalize() for word in model_name_lower.split('_'))
|
||||||
|
|
||||||
# 1. Get this client's subscription parameters for the specific model
|
# 1. Lấy các tham số đăng ký của client này cho model cụ thể
|
||||||
client_params = self.subscription_params.get(model_name_capitalized)
|
client_params = self.subscription_params.get(model_name_pascal_case)
|
||||||
if not client_params:
|
if not client_params:
|
||||||
return # This client is not subscribed to this model.
|
return # Client này không đăng ký model này.
|
||||||
|
|
||||||
# 2. Handle DELETION event
|
# 2. Xử lý sự kiện DELETION
|
||||||
if change_type == 'deleted':
|
if change_type == 'deleted':
|
||||||
await self.send_json({
|
|
||||||
"type": "realtime_update",
|
|
||||||
"payload": {
|
|
||||||
"name": model_name_lower,
|
|
||||||
"change_type": "deleted",
|
|
||||||
"record": {"id": record_id}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
|
|
||||||
# 3. Handle CREATION and UPDATE events
|
|
||||||
Model, _ = get_serializer(model_name_lower)
|
|
||||||
if not Model:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Build a Q object from the client's filter dictionary
|
|
||||||
filter_q = Q()
|
|
||||||
filter_dict = client_params.get('filter')
|
|
||||||
if isinstance(filter_dict, dict):
|
|
||||||
filter_q = Q(**filter_dict)
|
|
||||||
|
|
||||||
# Check if the object actually exists with the combined filter
|
|
||||||
record_exists = await database_sync_to_async(
|
|
||||||
Model.objects.filter(Q(pk=record_id) & filter_q).exists
|
|
||||||
)()
|
|
||||||
|
|
||||||
if record_exists:
|
|
||||||
# If record matches filter, re-run the query to get the correctly shaped data
|
|
||||||
single_record_params = client_params.copy()
|
|
||||||
single_record_params['filter'] = {'pk': record_id}
|
|
||||||
|
|
||||||
data = await database_sync_to_async(execute_data_query)(model_name_capitalized, single_record_params)
|
|
||||||
|
|
||||||
if data and data.get('rows'):
|
|
||||||
payload_for_client = {
|
|
||||||
"name": model_name_lower,
|
|
||||||
"change_type": change_type,
|
|
||||||
"record": data['rows'][0]
|
|
||||||
}
|
|
||||||
await self.send_json({
|
await self.send_json({
|
||||||
"type": "realtime_update",
|
"type": "realtime_update",
|
||||||
"payload": payload_for_client
|
"payload": {
|
||||||
|
"name": model_name_lower,
|
||||||
|
"change_type": "deleted",
|
||||||
|
"record": {"id": record_id}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
else:
|
return
|
||||||
# If the record exists but no longer matches the filter, treat as a deletion for this client
|
|
||||||
await self.send_json({
|
# 3. Xử lý sự kiện CREATION và UPDATE
|
||||||
"type": "realtime_update",
|
Model, _ = get_serializer(model_name_lower)
|
||||||
"payload": {
|
if not Model:
|
||||||
"name": model_name_lower,
|
return
|
||||||
"change_type": "deleted",
|
|
||||||
"record": {"id": record_id}
|
# Xây dựng một đối tượng Q từ từ điển bộ lọc của client
|
||||||
}
|
filter_q = Q()
|
||||||
})
|
filter_dict = client_params.get('filter')
|
||||||
|
if isinstance(filter_dict, dict):
|
||||||
|
filter_q = Q(**filter_dict)
|
||||||
|
|
||||||
|
# Kiểm tra xem đối tượng có thực sự tồn tại với bộ lọc kết hợp không
|
||||||
|
record_exists = await database_sync_to_async(
|
||||||
|
Model.objects.filter(Q(pk=record_id) & filter_q).exists
|
||||||
|
)()
|
||||||
|
|
||||||
|
if record_exists:
|
||||||
|
# Nếu bản ghi khớp với bộ lọc, chạy lại truy vấn để lấy dữ liệu có định dạng đúng
|
||||||
|
single_record_params = client_params.copy()
|
||||||
|
single_record_params['filter'] = {'pk': record_id}
|
||||||
|
|
||||||
|
data = await database_sync_to_async(execute_data_query)(model_name_pascal_case, single_record_params)
|
||||||
|
|
||||||
|
if data and data.get('rows'):
|
||||||
|
payload_for_client = {
|
||||||
|
"name": model_name_lower,
|
||||||
|
"change_type": change_type,
|
||||||
|
"record": data['rows'][0]
|
||||||
|
}
|
||||||
|
await self.send_json({
|
||||||
|
"type": "realtime_update",
|
||||||
|
"payload": payload_for_client
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
# Nếu bản ghi tồn tại nhưng không còn khớp với bộ lọc, coi như là một thao tác xóa đối với client này
|
||||||
|
await self.send_json({
|
||||||
|
"type": "realtime_update",
|
||||||
|
"payload": {
|
||||||
|
"name": model_name_lower,
|
||||||
|
"change_type": "deleted",
|
||||||
|
"record": {"id": record_id}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
print(f"!!!!!!!!!! EXCEPTION in realtime_update: {e} !!!!!!!!!!!")
|
||||||
|
traceback.print_exc()
|
||||||
|
|||||||
Reference in New Issue
Block a user