Django初识
模板渲染JinJa2
之前使用代码实现了一个简单的动态页面(字符串替换),我完全可以从数据库中查询数据,然后去替换我html中的对应内容(专业名词叫做模板渲染,你先渲染一下,再给浏览器进行渲染),然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2
下载:
pip3 install jinja2
创建一个html文件,index2,html,内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1>姓名:{{name}}</h1> <h1>爱好:</h1> <ul> {% for hobby in hobby_list %} <li>{{hobby}}</li> {% endfor %} </ul> </body> </html>
使用jinja2渲染index2.html文件,创建一个python文件,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from wsgiref.simple_server import make_server from jinja2 import Template def index(): with open("index2.html", "r", encoding='utf-8') as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({"name": "于谦", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面 return [bytes(ret, encoding="utf8"), ] # 定义一个url和函数的对应关系 URL_LIST = [ ("/index/", index), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None # 将要执行的函数 for i in URL_LIST: if i[0] == url: func = i[1] # 去之前定义好的url列表里找url应该执行的函数 break if func: # 如果能找到要执行的函数 return func() # 返回函数的执行结果 else: return [bytes("404没有该页面", encoding="utf8"), ] if __name__ == '__main__': httpd = make_server('', 9001, run_server) print("Serving HTTP on port 9001...") httpd.serve_forever()
使用pymysql连接数据库:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import pymysql conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",db="day53",charset="utf-8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute("select name,hobby from user") user_list = cursor.fetchall() cursor.close() conn.close()
模板的原理就是字符串替换,我们只要在HTML页面中遵循jinja2的语法规则写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容。
MVC和MTV框架
MVC框架
之前写的那个自定义框架就输MVC框架的
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
MTV框架
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)
T 代表模板 (Template):负责如何把页面展示给用户(html)
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
Django下载安装
1.下载Django
pip3 install django==1.11.9
配置环境变量:scripts那个路径配置到环境变量里面
2.创建一个Django项目
django-admin startproject mysite # 创建了一个名为"mysite"的Django 项目
或者在pycharm中创建
创建好之后会有相应的结构:
manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件。
settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
urls.py ----- 负责把URL模式映射到应用程序。
wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,所有与socket相关的内容都在这个文件里面了。
启动项目:
python manage.py runserver 127.0.0.1:8080 #此时已经可以启动django项目了,只不过什么逻辑也没有呢
3.在项目目录下创建应用
创建app: django-admin startapp 应用名(app01)
python manage.py startapp 应用名
python manage.py startapp blog #通过执行manage.py文件来创建应用,执行这句话一定要注意,你应该在这个manage.py的文件所在目录下执行这句话,因为其他目录里面没有这个文件
python manage.py startapp blog2 #每个应用都有自己的目录,每个应用的目录下都有自己的views.py视图函数和models.py数据库操作相关的文件
models.py :之前我们写的那个名为model的文件就是创建表用的,这个文件就是存放与该app(应用)相关的表结构的
views.py :存放与该app相关的视图函数的
cmd:
注册app,settings配置文件中:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', # 'app02.apps.App02Config', 'app02', ]
pycharm中创建点击:
4.启动Django项目
python manage.py runserver 8080 # python manage.py runserver 127.0.0.1:8080,本机就不用写ip地址了 如果连端口都没写,默认是本机的8000端口
访问:http://127.0.0.1:8080/时就可以看到
在pycharm中启动点击:
基于Django实现一个简单的示例
还是和之前一样,表单验证用户名密码登录,成功返回success页面,验证不成功提示即可。
url控制器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""mydjango URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), # 这个不用管,注释掉 url(r'^index/', views.index), ]
视图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render, HttpResponse
# Create your views here.
def index(request):
# 判断请求方式,如果是GET返回index页面
if request.method == "GET":
return render(request, "index.html")
# 非GET在这里也就是POST,验证表单,成功返回success页面
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "wubiao" and password == "123456":
# 返回success页面并且替换之前name对应信息(和jinja2类似但不是)
return render(request, "success.html", {"name": username})
else:
return HttpResponse("错了!!!")
模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h1>欢迎来到index</h1> <form action="/index/" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="password"> <input type="submit"> </form> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <h1>恭喜{{ name }}啊,登录成功了!!!</h1> </body> </html>
模板放在templates文件夹下
更改端口:
运行试下
地址栏输入:
页面成功跳转:
输入正确的用户名密码试下,点击提交,成功跳转并且替换username生效。
密码输入错误尝试,同样也提示信息。
好了,简单的小测试完成
注意!!!
在settings配置文件里面有关于templates(放html文件的配置):
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] #有些版本的django没有写这个,自己写一下,就是配置一个django找html文件的路径,render方法就来这里找html文件 , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
所以,关于请求和响应的请求信息和相应信息的设置不需要自己写的。
post请求的时候你会发现一个 Forbidden的错误:
现在只需要做一步,在settings配置文件里面将这一行注释掉,这是django给你加的一个csrf的认证,现在不需要。
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]