• 我们在哪一颗星上见过 ,以至如此相互思念 ;我们在哪一颗星上相互思念过,以至如此相互深爱
  • 我们在哪一颗星上分别 ,以至如此相互辉映 ;我们在哪一颗星上入睡 ,以至如此唤醒黎明
  • 认识世界 克服困难 洞悉所有 贴近生活 寻找珍爱 感受彼此

python模块: django-web服务建设过程中的知识

python知识点 云涯 4年前 (2020-03-08) 1519次浏览

允许其他IP访问:在setting中更改成

ALLOWED_HOSTS = ['*']

在根目录增加static后要在settin中写上:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

内网其他机器可以访问:runserver 0.0.0.0:8000


主url调用其他url:

path('index/', include('index.urls')),

多文件上传:

<input multiple="multiple" type="file" name="path" id='src_file'......

multiple=”multiple” 可以保证在选择文件的时候按住ctrl进行选择多个文件。以下是ajax异步上传多个文件的代码。

该代码解决了多个问题,第一是上传多个文件,利用for循环进行多个文件添加,否则就只能传第一个。

 for(i = 0; i< $('#src_file')[0].files.length; i++)
{
    formdata.append('src_file', $('#src_file')[0].files[i]);
}

第二个就是csrf的问题。

var csrf_data=$('input[name=csrfmiddlewaretoken]').val();
formdata.append('csrfmiddlewaretoken',csrf_data);

以下是完整前端代码

    $('#submit').click(function () {
        var i= 0;
        var formdata = new FormData();
        var csrf_data=$('input[name=csrfmiddlewaretoken]').val();
        formdata.append('csrfmiddlewaretoken',csrf_data);

        for(i = 0; i< $('#src_file')[0].files.length; i++)
        {
               formdata.append('src_file', $('#src_file')[0].files[i]);
        }
        $.ajax({
            type:'post',
            url:'/index/',
            data:formdata,
            processData:false,
            contentType:false,
            success:function (arg) {
                console.log(arg);}
            });
    })
</script>

以下是python后端代码,获得多个文件的关键是getlist函数,不能用get函数。

dirlist = request.FILES.getlist("src_file")  # 获取文件列表
for file in dirlist:
position = os.path.join('./results/源文档/'+username+'/', str(file))
# 获取上传文件的文件名,并将其存储到指定位置
storage = open(position, 'wb+') # 打开存储文件
for chunk in file.chunks(): # 分块写入文件
storage.write(chunk)
storage.close() # 写入完成后关闭文件

在做django过程中,我想在界面做一个像调试窗口信息显示的部分,能显示程序运行到何处以及产生的错误。我把目光投向了django的websocket。使用了dwebsocket模块进行开发。

在setting中INSTALLED_APPS中加上“dwebsocket”。

以下是websocket的前端通信代码

{#websocket通信#}
    <script>
        window.onload =function () {
            var username = '{{ request.session.user_name }}';
            if ("WebSocket" in window) {
                document.getElementById("yunxing").value = "您的浏览器支持 WebSocket!";
                var ws = new WebSocket("ws://" + window.location.host + "/index/websocket/"+ username);
                ws.onopen = function () {
                    document.getElementById("yunxing").value += "\n成功链接服务器!";
                    ws.send($('#message').val())  };

                ws.onmessage = function (evt) {
                    var received_msg = evt.data;
                    document.getElementById("yunxing").value += "\n"+received_msg;  };

                ws.onclose = function () {
                    document.getElementById("yunxing").value += "\n链接关闭";  };

            }
            else {alert("您的浏览器不支持 WebSocket!");}
    }</script>

第一为了实现区别用户,所以创建了登录窗口,用“用户名”区分不用用户,来进行点对点的消息发送,否则使用者打开,该部分就会显示其他人运行的提示信息。所以在前端就有了获取用户名的代码   var username = ‘{{ request.session.user_name }}’;通过for message in request.websocket: 以及request.websocket.send(message)来维持通道,否则通道就会关闭。下面的websocketMsg函数就是为了应对一个账号打开多个窗口的问题,保证信息都要发到位。

clients = {} # 字典,用来存储多个用户
@accept_websocket
def websocket(request, username):
    if request.is_websocket:
        lock = threading.RLock()  # 多线程锁
        try:
            lock.acquire()
            s = {}
            if clients.get(username) is not None:
                s[str(request.websocket)] = request.websocket
                clients[username].update(s)

            else:
                #  连接信息  键 连接名  值:连接保存
                s[str(request.websocket)] = request.websocket
                # 新增 用户  连接信息
                clients[username] = s
            glo.set_value("clients", clients)
            for message in request.websocket:
                if not message:
                    break

                else:
                    if message == b'undefined':
                        message = {
                            'time': time.strftime('%Y.%m.%d %H:%M:%S', time.localtime(time.time()))
                        }
                        request.websocket.send(json.dumps(message))
                    else:
                        request.websocket.send(message)
        finally:
            clients.get(username).pop(str(request.websocket))
            lock.release()


def websocketMsg(client, message):
    for cli in client:
        'client客户端 ,msg消息'
        client[cli].send(message)

第二个问题就是如何跨app,或者说跨不同的py文件,还能调用当前websocket进行信息发送呢?!我在一个单独的py文件中做了一个全局函数,进行变量的传递,那传递的就是当前的用户名以及维持websocket的session内容。那也就是为什么上面代码有 glo.set_value(“clients”, clients),就是为了通过下面代码的py文件进行session传递,也就是提到的clients传递。

global global_dict
global_dict = {}


def set_value(key, value):
    """ 定义一个全局变量 """
    global_dict[key] = value


def get_value(key, defValue=None):
    """ 获得一个全局变量,不存在则返回默认值 """

    try:
        return global_dict[key]
    except KeyError:
        return defValue

这样,在其他py文件想要通过websocket进行发送消息的时候,只需要把clients字典,也就是正在访问web服务的所有用户的session都传递过来,然后通过username进行请求,点对点的发给所请求的username。这样就完成了跨文件的消息传递。

clients = glo.get_value('clients')
username = request.session['user_name']
views.websocketMsg(clients[username], 'Log cleared')

 


云涯历险记 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python模块: django-web服务建设过程中的知识
喜欢 (1)