Django的视图函数和路由系统中一些没有用过的小点详解编程语言

1、request对象

    print("返回用户访问的url,但是不包括域名",request.path_info) 
    print("返回请求的方法,全大写",request.method) 
    print("返回HTTPde GET参数的类的字典对象",request.GET) 
    print("返回HTTPde POST参数的类的字典对象", request.POST) 
    print("请求体",request.body) 

  

结果如下:

Django的视图函数和路由系统中一些没有用过的小点详解编程语言

2、form上传文件 

首先看下form表单该如何写

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Title</title> 
</head> 
<body> 
<form method="post" action="/app1/upload/" enctype="multipart/form-data"> 
    {% csrf_token %} 
    <input type="file" placeholder="上传文件" name="file"> 
    <input type="submit" value="提交"> 
 
</form> 
</body> 
</html> 

  

重点是这里

Django的视图函数和路由系统中一些没有用过的小点详解编程语言

然后看下后端视图函数,用request.FILES方法获取上传的文件的对象

def upload(request): 
    method = request.method.lower() 
    if method == "get": 
        return render(request,"upload.html") 
    else: 
        # print(dir(request)) 
 
        file_name = request.FILES["file"].name 
 
        name = request.FILES.get("file").name 
        size = request.FILES.get("file").size 
        print("---------->",dir(request.FILES.get("file"))) 
        print(name,size) 
        import os 
        new_file_path = os.path.join("static","upload",name) 
        with open(new_file_path,"wb") as f: 
            for chunks in request.FILES.get("file").chunks(): 
                f.write(chunks) 
 
 
        return HttpResponse(file_name) 

  

3、视图函数返回json字符串的三种方法

def js(request): 
    ret = {"name":"xiaocui","age":23} 
 
    # 视图函数返回json字符串,有下面三种方法 
 
 
    # 方法1 
    import json 
 
    return HttpResponse(json.dumps(ret)) 
 
 
    # 方法2 
 
    from django.http import JsonResponse 
    return JsonResponse(ret) 
 
    # 默认情况下JsonResponse只能转换字典为js的字符串,如果是列表是转换不成jsson的字符串d的,如果要转换列表为js字符串则使用下面的方法 
 
     
    # 方法3 
    from django.http import JsonResponse 
    return JsonResponse(ret,safe=False) 
     
    # 告诉JsonResponse不要为我做安全监察 

  

4、路由系统中的别名

我们可以为urls.py中的路由系统取一个别名,这样,如果我们的匹配规则变了,我们还是可以通过别名去访问这个路由映射的函数,用法如下

urlpatterns = [ 
    url(r'^publish/', views.publish,name="publish_index"), 
    url(r'^add_publish/', views.addpublish,name="publish_add"), 
    url(r'^del_publish/', views.delpublish,name="publish_del"), 
    url(r'^edit_publish/', views.editpublish,name="publish_edit"), 
    url(r'^auther/', views.auther,name="auther_index"), 
    url(r'^book/', views.book,name="book_index"), 
    url(r'^add_book/', views.addbook,name="book_add"), 
    url(r'^edit_book/', views.editbook,name="book_edit"), 
    url(r'^test/', views.test,name="test"), 
    url(r'^upload/', views.upload,name="upload"), 
    url(r'^js/', views.js,name="js"), 
    # url(r'^base/', views.base), 
    url(r'^router/[0-9]{1,3}/[a-z]{1,3}/$', views.router, name="router"), 
    url(r'^router_one/([0-9]{1,3})/([a-z]{1,3})/$', views.router_one, name="router_one"), 
    url(r'^router_two/(?P<arg2>[0-9]{1,3})/(?P<arg3>[a-z]{1,3})/$', views.router_two, name="router_two"), 
    url(r'^url1/', views.url1,name="url_one"), 
    url(r'^url2/', views.url2,name="url_two"), 
 
] 

  

这个name就是我们为这条路由取的别名,那么我们在html文件中就可以通过别名去访问这个路由,记住,这里对应的别名需要用单引号括起来才能生效

<a href="{% url 'url_two' %}">跳转到url2</a> 

  

 如果urls中的别名对应的路由需要传递参数,我们该如何传递呢,在html中传递参数,只能通过位置参数来传递,传递的方法如下

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Title</title> 
</head> 
<body> 
<h1>url1的主页</h1> 
<p>友情链接</p> 
<a href="{% url 'router_two' '123' 'abc' %}">跳转到url2</a> 
</body> 
</html> 

  

这个a标签跳转到router_two这个命令别名对应的路由,我们在看这个路由

    url(r'^router_two/(?P<arg2>[0-9]{1,3})/(?P<arg3>[a-z]{1,3})/$', views.router_two, name="router_two"), 

  

所有arg2就是“123”,arg3就是“abc”

上面我们介绍的是在html文件中使用url的别名,我们还可以在视图函数中使用路由别名

需要导入一个reverse模块,然后通过这个模块找到别名对应的url,然后通过redirect返回找到的url就可以了

from django.urls import reverse 
 
def url3(request): 
    red_url = reverse("publish_index") 
 
    return redirect(red_url) 

  

同样,如果视图函数需要传递参数,在视图函数中该如何传递参数呢,可以使用下面的方式

def url3(request): 
    red_url = reverse("router_two",kwargs={"arg2":"123","arg3":"aaa"}) 
 
    return redirect(red_url) 

  

这样,指定red_url对应的路由,会传递2个参数过去,arg2为123,arg3为aaa,这个是分组命令匹配

如果分组位置匹配,则传递参数就不能用kwargs了,需要用args=(“123″,”aaa”),则123就会赋值给url中的第一个参数,aaa就会赋值给url中的第二个参数

5、路由系统中的参数匹配

    url(r'^router/[0-9]{1,3}/[a-z]{1,3}/$', views.router, name="router"), 
    url(r'^router_one/([0-9]{1,3})/([a-z]{1,3})/$', views.router_one, name="router_one"), 
    url(r'^router_two/(?P<arg2>[0-9]{1,3})/(?P<arg3>[a-z]{1,3})/$', views.router_two, name="router_two"), 

  

第一条路由映射不会向后台传递任何参数,仅仅是是一个正则的匹配规则

def router(request): 
    l = ["aa","bb","cc","dd"] 
    from django.http import JsonResponse 
    return JsonResponse(l,safe=False) 

  

第二条路由映射会向后台传递参数,传递的位置参数,因为这里有2个括号,所以在视图函数中必须要接受3个形参,第一个是request,第二个是第一个括号中匹配到的字符串,第三个是第二个括号中匹配到的字符串

def router_one(request,arg1,arg2): 
 
    l = [] 
    l.append(arg1) 
    l.append(arg2) 
 
    from django.http import JsonResponse 
 
    return JsonResponse(l,safe=False) 

  

第三条路由映射向后台传递参数,传递的命名参数,其中第一个括号中的字符串被赋值给变量arg2,第二个括号中的字符串会赋值给变量arg3,这样,我们在视图函数中可以通过arg2和arg3来获取url中匹配到的字符串

def router_two(request,arg2,arg3): 
    l = [] 
    l.append(arg2) 
    l.append(arg3) 
 
    from django.http import JsonResponse 
 
    return JsonResponse(l,safe=False) 

  

django中的request参数中有很多的方法

['COOKIES', 'FILES', 'GET', 'POST', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__it 
er__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_encoding', '_get_post', '_get_ 
raw_host', '_get_scheme', '_initialize_handlers', '_load_post_and_files', '_mark_post_parse_error', '_set_post', '_upload_handlers', 'body', 'build_absolute_uri', 'close', 'encoding', 'get_full_path', 'get_host', 
 'get_port', 'get_raw_uri', 'get_signed_cookie', 'is_ajax', 'is_secure', 'parse_file_upload', 'read', 'readline', 'readlines', 'scheme', 'upload_handlers', 'xreadlines'] 

  

这里有有个很重要的属性就是META,这里包含很多的信息,他是字典,我们可以通过get方法去获取我们需要的属性,必须客户端的ip之类的信息

{'LOCALAPPDATA': 'C://Users//Administrator//AppData//Local', 'PROCESSOR_LEVEL': '6', 'FP_NO_HOST_CHECK': 'NO', 'PROMPT': '$P$G', 'USERDOMAIN': 'VDP', 'LOGONSERVER': '////WIN-B5TQAQI491H', 'JAVA_HOME': 'C://Progra 
m Files//Java', 'SESSIONNAME': 'RDP-Tcp#0', 'ALLUSERSPROFILE': 'C://ProgramData', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PSMODULEPATH': 'C://Windows//system32//WindowsPowerShell//v1.0//Modules//', 'SYSTEMDRIVE': 'C: 
', 'JRE_HOME': 'C://Program Files//Java//jre7', 'APPDATA': 'C://Users//Administrator//AppData//Roaming', 'MOZ_PLUGIN_PATH': 'C://Program Files (x86)//Foxit Software//Foxit Reader//plugins//', 'USERNAME': 'Adminis 
trator', 'USERDNSDOMAIN': 'VDP.COM', 'WINDOWS_TRACING_LOGFILE': 'C://BVTBin//Tests//installpackage//csilogfile.log', 'PROGRAMFILES(X86)': 'C://Program Files (x86)', 'COMMONPROGRAMFILES': 'C://Program Files//Commo 
n Files', 'PATH': 'C://ProgramData//Oracle//Java//javapath;C://Program Files (x86)//Common Files//NetSarang;C://Windows//system32;C://Windows;C://Windows//System32//Wbem;C://Windows//System32//WindowsPowerShell// 
v1.0//;C://Program Files//FalconStor//IMA//;C://Windows//idmu//common;C://Program Files//MySQL//MySQL Utilities 1.6//;C://Program Files//Python36//Scripts//;C://Program Files//Python36;C://sqlite;C://Program File 
s//Java//jdk1.7.0_51//bin;C://Program Files//Java//jre7//bin', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'OS': 'Windows_NT', 'WINDOWS_TRACING_FLAGS': '3', 'COMPUTERNAME': 'WIN-B5TQAQI491 
H', 'PROCESSOR_REVISION': '3a09', 'COMMONPROGRAMW6432': 'C://Program Files//Common Files', 'COMSPEC': 'C://Windows//system32//cmd.exe', 'PROGRAMDATA': 'C://ProgramData', 'PROGRAMW6432': 'C://Program Files', 'HOME 
PATH': '//Users//Administrator', 'SYSTEMROOT': 'C://Windows', 'TEMP': 'C://Users//ADMINI~1//AppData//Local//Temp//2', 'HOMEDRIVE': 'C:', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 58 Stepping 9, GenuineIntel 
', 'USERPROFILE': 'C://Users//Administrator', 'TMP': 'C://Users//ADMINI~1//AppData//Local//Temp//2', 'COMMONPROGRAMFILES(X86)': 'C://Program Files (x86)//Common Files', 'PROGRAMFILES': 'C://Program Files', 'PUBLI 
C': 'C://Users//Public', 'NUMBER_OF_PROCESSORS': '8', 'WINDIR': 'C://Windows', 'CLIENTNAME': 'SANGFOR-PC', 'DJANGO_SETTINGS_MODULE': 'hadoop_project.settings', 'RUN_MAIN': 'true', 'SERVER_NAME': 'WIN-B5TQAQI491H. 
vdp.com', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8080', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': ' 
GET', 'PATH_INFO': '/admin/jsi18n/', 'QUERY_STRING': '', 'REMOTE_ADDR': '200.200.216.215', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '10.87.6.1:8080', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_USER_AGENT': 'Mozilla 
/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', 'HTTP_ACCEPT': '*/*', 'HTTP_REFERER': 'http://10.87.6.1:8080/admin/app1/projecttalbe/', 'HTTP_ACCEPT_ENCODING': 'g 
zip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'csrftoken=xQpWwE2TEG8gM4O7M8EwN4uUxiC4cTaL8BmQ6lirfnwdscir1DMLxCWLGobBL1SX; sessionid=53lverenz02qbpk0lywk25ydqug8p8ib', 'wsgi.input': <_io 
.BufferedReader name=668>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi. 
multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>} 

  

这里我们就在中间件的通过request的META方法获取客户端的ip,然后进行序列化存储

import json 
import os 
class My_first_middle(MiddlewareMixin): 
 
    def process_request(self,request): 
        a = os.path.abspath(__file__) 
        file_path = os.path.dirname(os.path.dirname(a)) + "//" + "request_ip.text" 
        file_obj = open(file_path, "r", encoding="utf-8") 
        client_ip_list = json.load(file_obj) 
 
        # print(client_ip_list,type(client_ip_list)) 
        # print(request.get_full_path()) 
 
        client_ip = request.META.get("REMOTE_ADDR") 
        print(dir(request)) 
        print(request.META) 
        if client_ip in client_ip_list: 
            pass 
 
        else: 
            client_ip_list.append(client_ip) 
 
        for m,n in enumerate(client_ip_list,1): 
            print(m,n,sep="------------>") 
 
        print("这是一个中间件的process_request") 
 
 
        file_obj = open(file_path,"w",encoding="utf-8") 
 
        json.dump(client_ip_list,file_obj,indent=4) 

  

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/20808.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论