开发者社区 问答 正文

django怎样在两个VIEWS之间传递数据

from django.shortcuts import render
from django.views.generic.base import View
from datetime import datetime
from django.http import HttpResponse
from .models import Cschat
from tools.cschat_aliyun import AliyunCschat
from django.views.decorators.csrf import csrf_exempt
import json,time


class CschatView(View):
    def get(self,request):
        return render(request,'cschat.html')

    def post(self,request):
        content = request.POST.get("content","")
        result = AliyunCschat(content).hash_result()
        time.sleep(2)
        with open('aliyun.json','rb') as f:
            d = json.loads(f.read())
        return render(request,'cschat_result.html',{
            "contents":d
        })


class AliyunCallbackView(View):
    @csrf_exempt
    def post(self,request):
        postbody = request.body
        with open('aliyun.json','wb') as f:
            f.write(postbody)
        return HttpResponse(str(postbody))

    def get(self,request):
        return render(request,'aliyun_callback.html',{
            "text":"没有结果"
        })

应用场景:给阿里云的接口发送POST请求后 阿里云不会直接返回数据 而是把数据返回到另外一个接口(class AliyunCallbackView(View)这个对应的url),我需要在给阿里云发送POST请求后从另一个接口读取阿里云返回的POST数据。

代码中

result = AliyunCschat(content).hash_result()

这一行执行是给阿里云的接口发送POST请求 我现在的写法很有问题,因为没有好的解决办法。 我的做法是把AliyunCallbackView接收到的阿里云POST返回的数据写到aliyun.json这个文件里面,然后等待2秒钟后读取aliyun.json里面的内容,再把结果返回给前端。这样写的问题很多,如果AliyunCallbackView在一秒内接收到多个返回数据,那后面的执行内容就全变了。可以把阿里云POST返回的数据写入数据库,然后使用时间戳查询数据库返回对应的值。这种办法虽然可行但是感觉太麻烦了,请问有什么更好的解决办法?

遇到了同样的问题,在CSDN看到了,希望阿里云团队能够给出正确、标准的答案~请查看

展开
收起
刘刚_ 2020-05-23 21:06:45 1054 分享 版权
阿里云 AI 助理回答

在您的场景中,确实存在并发写入文件可能导致数据混乱的问题,而频繁查询数据库也并非最优解。一个更高效且线程安全的方案是使用消息队列(如阿里云的MQ服务)来处理异步回调和结果传递。这样可以确保请求与响应之间的解耦,提高系统的可扩展性和稳定性。

以下是基于此思路的一个简化示例流程:

  1. 发送请求到阿里云接口:保持不变,但不再直接等待结果。

  2. 设置消息队列:在发送请求前,生成一个唯一的标识符(如UUID),将这个标识符连同请求内容一起发送给阿里云,并将该标识符作为消息ID保存至消息队列中。此时,消息队列中存储的是待处理的请求信息及用于关联的唯一ID。

  3. 阿里云回调处理:当阿里云通过AliyunCallbackView接收到数据时,根据之前生成的唯一标识符从消息队列中查找对应的消息。然后更新这条消息的内容为阿里云返回的数据。这里利用消息队列的幂等性处理机制,确保即使多次回调也不会导致数据重复或错乱。

  4. 前端轮询或长轮询:前端可以通过AJAX定期查询(或者使用WebSocket实现长连接)后端接口,提供之前生成的唯一标识符。后端根据这个标识符从消息队列中检查是否有对应的结果,如果有,则返回给前端;如果没有,则返回“正在处理”状态,直到超时或有结果。

  5. 后端查询逻辑:创建一个新的视图函数,接收前端传来的唯一标识符,查询消息队列中对应的消息状态。如果消息已包含阿里云的响应数据,则直接返回给前端;否则,可以设计合理的重试逻辑或让前端继续轮询。

采用这种方式,您不仅解决了并发问题,还使得系统更加健壮、可扩展。阿里云提供了多种消息队列服务,如RocketMQ、Kafka等,可以根据实际需求选择适合的服务进行集成。

请注意,上述方案需要您对现有代码结构做较大调整,并引入新的组件(消息队列服务)。此外,还需考虑如何管理消息的有效期、失败处理策略等细节。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答标签:
问答地址: