06 django视图层
视图层
视图就是一个函数,请求过来后要做什么事情都在这个函数里,也就是具体处理请求的功能。
熟练掌握两个视图层对象:请求对象(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.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 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据 51 # FILES 只有在请求为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况才会包含数据。否则,FILES 将为一个空的类似于字典的对象。 52 print('FILES:\n', request.FILES) 53 54 # COOKIES 一个标准的Python 字典,包含所有的cookie。键和值都为字符串。 55 print('COOKIES:\n', request.COOKIES) 56 57 # session 一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。 58 print('session:\n', request.session) 59 60 # user 一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户 61 # 如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们 62 print('user:\n', request.user) 63 64 65 # request方法 66 # get_full_path 返回 path,如果可以将加上查询字符串,即get请求后面的查询参数,如:/app01/login/?a=1&b=2。 67 print('get_full_path:\n',request.get_full_path()) 68 69 # is_ajax 70 print('is_ajax:\n',request.is_ajax()) 71 '''如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。 72 大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。 73 如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 74 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存''' 75 76 if method.lower() == 'post': 77 # 如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。 78 # 注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:request.POST.getlist("hobby") 79 req_data = request.POST # 一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。 80 print('request.POST:\n',req_data) 81 user = req_data.get('user') 82 pwd = req_data.get('pwd') 83 mysql_check = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8") 84 sql = "select * from user_info WHERE name=%s and password=%s" 85 res = mysql_check.exec_sql(sql, user, pwd) 86 if res and isinstance(res,list): 87 return render(request, 'index.html') 88 else: 89 return HttpResponse('username or password is wrong!') 90 else: 91 print('request.GET:\n',request.GET) # 一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象 92 return render(request, 'login.html')
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") # 传递要重定向的一个硬编码的URL 20 return redirect("http://127.0.0.1:8080/app01/index/") # 也可以是一个完整的URL 21 ''' 22 1)301和302的区别。 23 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取 24 (用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 25 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址; 26 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 302好于301 27 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 admin from django.urls import path,re_path,include urlpatterns = [ 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 # Internationalization 105 # https://docs.djangoproject.com/en/2.2/topics/i18n/ 106 107 LANGUAGE_CODE = 'en-us' 108 109 TIME_ZONE = 'UTC' 110 111 USE_I18N = True 112 113 USE_L10N = True 114 115 USE_TZ = True 116 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 views from django.urls import path,re_path urlpatterns = [ 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 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据 51 # FILES 只有在请求为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况才会包含数据。否则,FILES 将为一个空的类似于字典的对象。 52 print('FILES:\n', request.FILES) 53 54 # COOKIES 一个标准的Python 字典,包含所有的cookie。键和值都为字符串。 55 print('COOKIES:\n', request.COOKIES) 56 57 # session 一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。 58 print('session:\n', request.session) 59 60 # user 一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户 61 # 如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们 62 print('user:\n', request.user) 63 64 65 # request方法 66 # get_full_path 返回 path,如果可以将加上查询字符串,即get请求后面的查询参数,如:/app01/login/?a=1&b=2。 67 print('get_full_path:\n',request.get_full_path()) 68 69 # is_ajax 70 print('is_ajax:\n',request.is_ajax()) 71 '''如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。 72 大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。 73 如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 74 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存''' 75 76 if method.lower() == 'post': 77 # 如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。 78 # 注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:request.POST.getlist("hobby") 79 req_data = request.POST # 一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。 80 print('request.POST:\n',req_data) 81 user = req_data.get('user') 82 pwd = req_data.get('pwd') 83 mysql_check = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8") 84 sql = "select * from user_info WHERE name=%s and password=%s" 85 res = mysql_check.exec_sql(sql, user, pwd) 86 if res and isinstance(res,list): 87 return render(request, 'index.html') 88 else: 89 return HttpResponse('username or password is wrong!') 90 else: 91 print('request.GET:\n',request.GET) # 一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象 92 return render(request, 'login.html') 93 94 95 # HttpResponse 对象 96 #响应对象主要有三种形式:HttpResponse() render() redirect() 97 def regist(request): 98 method = request.method 99 if method.lower() == 'post': 100 req_data = request.POST 101 user = req_data.get('user') 102 pwd = req_data.get('pwd') 103 if user and pwd: 104 mysql_check = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8") 105 sql = "select * from user_info WHERE name=%s" 106 res = mysql_check.exec_sql(sql, user) 107 if res and isinstance(res,list): 108 return HttpResponse('username is already exits!') 109 insert_sql = 'insert into user_info (name,password) VALUES (%s,%s) ' 110 mysql_check.exec_sql(insert_sql, user,pwd) 111 112 # redirect() 重定向 113 # return redirect("/app01/index") # 传递要重定向的一个硬编码的URL 114 return redirect("http://127.0.0.1:8080/app01/index/") # 也可以是一个完整的URL 115 ''' 116 1)301和302的区别。 117 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取 118 (用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 119 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址; 120 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 302好于301 121 2)重定向原因: 122 (1)网站调整(如改变网页目录结构); 123 (2)网页被移到一个新地址; 124 (3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。 125 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失; 126 再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。''' 127 128 # HttpResponse()括号内直接跟一个具体的字符串作为响应体。 129 return HttpResponse('username or password can not be empty !') 130 131 # render(request, template_name[, context]) 132 # 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。 133 # render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体 134 '''request: 用于生成响应的请求对象。 135 template_name:要使用的模板的完整名称,可选的参数 136 context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。''' 137 return render(request,'register.html',{'word':'hello world!'})
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 = host 12 self.port = port 13 self.user = user 14 self.pwd = pwd 15 self.dbname = dbname 16 self.charset = charset 17 self.conn = None # 给析构函数用的,如果存在链接,则需要关闭链接,没有就不用管 18 self.conn = self.get_conn 19 self.cur = None 20 self.cur = self.get_cur 21 22 @property 23 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 conn 30 else: 31 conn = pymysql.connect(host=self.host, port=self.port, user=self.user, 32 password=self.pwd, charset=self.charset) 33 return conn 34 except Exception as e: 35 print(e) 36 37 @property 38 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 res 59 else: 60 self.conn.commit() # 非查询语句需要提交才能生效 61 res = rows 62 return res 63 except Exception as e: 64 print(e) 65 return e 66 67 @staticmethod 68 def format_res(res): 69 """格式化数据库查找到的结果,如果""" 70 res_lis = [] 71 if res: 72 for i in res: 73 res_lis.append(i) 74 return res_lis 75 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 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>首页</title> 6 <style type="text/css"> 7 h3{ 8 margin: 10px 12px; 9 float: left; 10 overflow: hidden; 11 } 12 button{ 13 margin: 12px; 14 overflow: hidden; 15 } 16 </style> 17 </head> 18 <body> 19 <h3>欢迎进入首页 {{ word }}</h3> 20 <button id="btn_reg">注册</button> 21 <button id="btn_login">登陆</button> 22 <form action=""> 23 <img src="/static/index.jpg"> 24 </form> 25 </body> 26 <script type="text/javascript"> 27 window.onload = function () { 28 var tmp_reg = document.getElementById('btn_reg'); 29 var tmp_login = document.getElementById('btn_login'); 30 tmp_reg.onclick = function () { 31 window.open('/app01/regist',target='_self') 32 }; 33 tmp_login.onclick = function () { 34 window.open('/app01/login',target='_self') 35 } 36 } 37 </script> 38 </html>
04 django视图层\django_views\templates\register.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>注册</title> 6 </head> 7 <body> 8 <h3>注册 {{ word }}</h3> 9 <form action="{% url 'views_app01:reg' %}" method="post"> 10 <label for="user">用户名:</label> 11 <input type="text" name="user" id="user"> 12 <label for="pwd">密码:</label> 13 <input type="password" name="pwd" id="pwd"> 14 <input type="submit" value="注册"> 15 </form> 16 </body> 17 </html>
04 django视图层\django_views\templates\login.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登录</title> 6 </head> 7 <body> 8 <h3>登录</h3> 9 {#<form action="http://127.0.0.1:8080/app01/login/" method="post">#} 10 {# "{% url 'log' %}" 模板,log为url控制器里路径的别名#} 11 {#请求login页面,视图函数已经将 {% url 'log' %} 反向解析为配置的别名所指定的路径,返回的页面实际后台已经处理为如下#} 12 {#<form action="{% url 'log' %}" method="post"> -----> <form action="/app01/login/" method="post">#} 13 <form action="{% url 'views_app01:log' %}" method="post"> 14 <label for="user">用户名:</label> 15 <input type="text" name="user" id="user"> 16 <label for="pwd">密码:</label> 17 <input type="password" name="pwd" id="pwd"> 18 <input type="submit" value="登录"> 19 </form> 20 </body> 21 </html>
夕闻道不如朝闻道