视图层
视图就是一个函数,请求过来后要做什么事情都在这个函数里,也就是具体处理请求的功能。
熟练掌握两个视图层对象:请求对象(request)和响应对象(HttpResponse)。
HttpRequest对象
1 from django.shortcuts import render,redirect,HttpResponse 2 from views_app01.tools import Mysql 3 4 # Create your views here. 5 6 7 def index(request): 8 return render(request,'index.html',{ 'word':'嗯哼'}) 9 10 11 # HttpRequest对象12 def login(request):13 # request属性 django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性14 # body 是post请求参数,一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等15 print('request.body:\n',request.body)16 17 # method 请求方式 get post 等18 method = request.method19 print('method:\n',method)20 21 # path 一个字符串,表示请求的路径组件(不含域名)22 print('path:\n',request.path)23 24 # encoding 一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')25 # 这个属性是可写的,你可以修改它来修改访问表单数据使用的编码26 print('encoding:\n', request.encoding)27 28 # META 一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器29 print('META:\n', request.META)30 '''CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。31 CONTENT_TYPE —— 请求的正文的MIME 类型。32 HTTP_ACCEPT —— 响应可接收的Content-Type。33 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。34 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。35 HTTP_HOST —— 客服端发送的HTTP Host 头部。36 HTTP_REFERER —— Referring 页面。37 HTTP_USER_AGENT —— 客户端的user-agent 字符串。38 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。39 REMOTE_ADDR —— 客户端的IP 地址。40 REMOTE_HOST —— 客户端的主机名。41 REMOTE_USER —— 服务器认证后的用户。42 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。43 SERVER_NAME —— 服务器的主机名。44 SERVER_PORT —— 服务器的端口(是一个字符串)。45 从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,46 都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。47 所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。'''48 49 # FILES 一个类似于字典的对象,包含所有的上传文件信息50 # FILES 中的每个键为 中的name,值则为对应的数据51 # FILES 只有在请求为POST 且提交的
HttpResponse 对象
1 # HttpResponse 对象 2 #响应对象主要有三种形式:HttpResponse() render() redirect() 3 def regist(request): 4 method = request.method 5 if method.lower() == 'post': 6 req_data = request.POST 7 user = req_data.get('user') 8 pwd = req_data.get('pwd') 9 if user and pwd:10 mysql_check = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8")11 sql = "select * from user_info WHERE name=%s"12 res = mysql_check.exec_sql(sql, user)13 if res and isinstance(res,list):14 return HttpResponse('username is already exits!')15 insert_sql = 'insert into user_info (name,password) VALUES (%s,%s) '16 mysql_check.exec_sql(insert_sql, user,pwd)17 18 # redirect() 重定向19 # return redirect("/app01/index") # 传递要重定向的一个硬编码的URL20 return redirect("http://127.0.0.1:8080/app01/index/") # 也可以是一个完整的URL21 '''22 1)301和302的区别。23 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取24 (用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。25 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;26 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 302好于30127 2)重定向原因:28 (1)网站调整(如改变网页目录结构);29 (2)网页被移到一个新地址;30 (3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。31 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;32 再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。'''33 34 # HttpResponse()括号内直接跟一个具体的字符串作为响应体。35 return HttpResponse('username or password can not be empty !')36 37 # render(request, template_name[, context])38 # 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。39 # render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体40 '''request: 用于生成响应的请求对象。41 template_name:要使用的模板的完整名称,可选的参数42 context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。'''43 return render(request,'register.html',{ 'word':'hello world!'})
04 django视图层\django_views\django_views\urls.py
from django.contrib import adminfrom django.urls import path,re_path,includeurlpatterns = [ path('admin/', admin.site.urls), re_path(r'^app01/', include(('views_app01.urls','views_app01'))),]
04 django视图层\django_views\django_views\settings.py
1 """ 2 Django settings for django_views project. 3 4 Generated by 'django-admin startproject' using Django 2.2.3. 5 6 For more information on this file, see 7 https://docs.djangoproject.com/en/2.2/topics/settings/ 8 9 For the full list of settings and their values, see 10 https://docs.djangoproject.com/en/2.2/ref/settings/ 11 """ 12 13 import os 14 15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 18 19 # Quick-start development settings - unsuitable for production 20 # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 22 # SECURITY WARNING: keep the secret key used in production secret! 23 SECRET_KEY = '%ob8cq%r^)u&s@4fgd7qy+5$49ssg%+*-skaddqh1=a+@ypj33' 24 25 # SECURITY WARNING: don't run with debug turned on in production! 26 DEBUG = True 27 28 ALLOWED_HOSTS = [] 29 30 31 # Application definition 32 33 INSTALLED_APPS = [ 34 'django.contrib.admin', 35 'django.contrib.auth', 36 'django.contrib.contenttypes', 37 'django.contrib.sessions', 38 'django.contrib.messages', 39 'django.contrib.staticfiles', 40 'views_app01.apps.ViewsApp01Config', 41 ] 42 43 MIDDLEWARE = [ 44 'django.middleware.security.SecurityMiddleware', 45 'django.contrib.sessions.middleware.SessionMiddleware', 46 'django.middleware.common.CommonMiddleware', 47 # 'django.middleware.csrf.CsrfViewMiddleware', 48 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 'django.contrib.messages.middleware.MessageMiddleware', 50 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 ] 52 53 ROOT_URLCONF = 'django_views.urls' 54 55 TEMPLATES = [ 56 { 57 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 'DIRS': [os.path.join(BASE_DIR, 'templates')], 59 'APP_DIRS': True, 60 'OPTIONS': { 61 'context_processors': [ 62 'django.template.context_processors.debug', 63 'django.template.context_processors.request', 64 'django.contrib.auth.context_processors.auth', 65 'django.contrib.messages.context_processors.messages', 66 ], 67 }, 68 }, 69 ] 70 71 WSGI_APPLICATION = 'django_views.wsgi.application' 72 73 74 # Database 75 # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 76 77 DATABASES = { 78 'default': { 79 'ENGINE': 'django.db.backends.sqlite3', 80 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 } 82 } 83 84 85 # Password validation 86 # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 87 88 AUTH_PASSWORD_VALIDATORS = [ 89 { 90 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 }, 92 { 93 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 }, 95 { 96 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 }, 98 { 99 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',100 },101 ]102 103 104 # Internationalization105 # https://docs.djangoproject.com/en/2.2/topics/i18n/106 107 LANGUAGE_CODE = 'en-us'108 109 TIME_ZONE = 'UTC'110 111 USE_I18N = True112 113 USE_L10N = True114 115 USE_TZ = True116 117 118 # Static files (CSS, JavaScript, Images)119 # https://docs.djangoproject.com/en/2.2/howto/static-files/120 121 STATIC_URL = '/static/'122 123 STATICFILES_DIRS = [124 os.path.join(BASE_DIR,'statics'), # 指定静态文件地址,所有的静态文件都放这个目录125 ]126 127 TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
04 django视图层\django_views\views_app01\urls.py
from views_app01 import viewsfrom django.urls import path,re_pathurlpatterns = [ path('index/', views.index), re_path('^login/', views.login, name='log'), re_path('^regist/', views.regist, name='reg'),]
04 django视图层\django_views\views_app01\views.py
1 from django.shortcuts import render,redirect,HttpResponse 2 from views_app01.tools import Mysql 3 4 # Create your views here. 5 6 7 def index(request): 8 return render(request,'index.html',{ 'word':'嗯哼'}) 9 10 11 # HttpRequest对象 12 def login(request): 13 # request属性 django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性 14 # body 是post请求参数,一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等 15 print('request.body:\n',request.body) 16 17 # method 请求方式 get post 等 18 method = request.method 19 print('method:\n',method) 20 21 # path 一个字符串,表示请求的路径组件(不含域名) 22 print('path:\n',request.path) 23 24 # encoding 一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8') 25 # 这个属性是可写的,你可以修改它来修改访问表单数据使用的编码 26 print('encoding:\n', request.encoding) 27 28 # META 一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器 29 print('META:\n', request.META) 30 '''CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 31 CONTENT_TYPE —— 请求的正文的MIME 类型。 32 HTTP_ACCEPT —— 响应可接收的Content-Type。 33 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 34 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 35 HTTP_HOST —— 客服端发送的HTTP Host 头部。 36 HTTP_REFERER —— Referring 页面。 37 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 38 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 39 REMOTE_ADDR —— 客户端的IP 地址。 40 REMOTE_HOST —— 客户端的主机名。 41 REMOTE_USER —— 服务器认证后的用户。 42 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 43 SERVER_NAME —— 服务器的主机名。 44 SERVER_PORT —— 服务器的端口(是一个字符串)。 45 从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时, 46 都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。 47 所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。''' 48 49 # FILES 一个类似于字典的对象,包含所有的上传文件信息 50 # FILES 中的每个键为 中的name,值则为对应的数据 51 # FILES 只有在请求为POST 且提交的
04 django视图层\django_views\views_app01\tools.py
1 # -*- coding: utf-8 -*- 2 # @Time : 2019/7/16 10:42 3 # @Author : Xiao 4 5 import pymysql 6 7 8 class Mysql(object): 9 def __init__(self, host, port, user, pwd, dbname="", charset="utf8"):10 """初始化数据库信息以及连接"""11 self.host = host12 self.port = port13 self.user = user14 self.pwd = pwd15 self.dbname = dbname16 self.charset = charset17 self.conn = None # 给析构函数用的,如果存在链接,则需要关闭链接,没有就不用管18 self.conn = self.get_conn19 self.cur = None20 self.cur = self.get_cur21 22 @property23 def get_conn(self):24 """根据传参判断是否有传数据库名,然后做不同的链接操作"""25 try:26 if self.dbname:27 conn = pymysql.connect(host=self.host, port=self.port, user=self.user,28 password=self.pwd, database=self.dbname, charset=self.charset)29 return conn30 else:31 conn = pymysql.connect(host=self.host, port=self.port, user=self.user,32 password=self.pwd, charset=self.charset)33 return conn34 except Exception as e:35 print(e)36 37 @property38 def get_cur(self):39 """获取游标"""40 if self.conn:41 return self.conn.cursor()42 43 def exec_sql(self, sql, *args):44 """45 执行sql,根据不同的sql语法做不同的操作:46 查询就返回查询结果列表,其他成功就返回受影响的行数整型,报错返回报错信息字符串47 *args是为了防止sql注入,自己拼接的sql语法字符串可能被sql注入,48 这里的用法是sql不需要自己拼接,直接将变量按顺序传进来,pymysql自动拼接,而且避免了sql注入的问题49 如:50 sql = "insert into test.student VALUES (19,%s,'English',%s);"51 res = test_mysql.exec_sql(sql,"yangxga",100)52 """53 try:54 rows = self.cur.execute(sql, args) # rows记录受影响的行55 if sql.strip().lower().startswith('select') or sql.strip().lower().startswith('show'):56 res = self.cur.fetchall()57 res = self.format_res(res)58 return res59 else:60 self.conn.commit() # 非查询语句需要提交才能生效61 res = rows62 return res63 except Exception as e:64 print(e)65 return e66 67 @staticmethod68 def format_res(res):69 """格式化数据库查找到的结果,如果"""70 res_lis = []71 if res:72 for i in res:73 res_lis.append(i)74 return res_lis75 76 def __del__(self):77 """析构函数,关闭鼠标,断开连接"""78 if self.cur:79 self.cur.close()80 if self.conn:81 self.conn.close()
04 django视图层\django_views\templates\index.html
1 2 3 4 525 26 38首页 6 17 18 19欢迎进入首页 { { word }}
20 21 22
04 django视图层\django_views\templates\register.html
1 2 3 4 516 17注册 6 7 8注册 { { word }}
9
04 django视图层\django_views\templates\login.html
1 2 3 4 520 21登录 6 7 8登录
9 {#