一、MVC框架和MTV框架(了解即可)
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。
Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架。
2.1 Django的MTV模式
Model(模型):负责业务对象与数据库的对象(ORM)
Template(模版):负责如何把页面展示给用户
View(视图):负责业务逻辑,并在适当的时候调用Model和Template
此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template
2.2 Django框架图示
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
二、Django下载安装
2.1 安装(安装最新LTS版)
pip3 install django==1.11.9
Django我们用的是1.11.9版本,大版本就是一版本,不要下载2版本。有一些功能是有差别的。
我们下载的类似于一个模块,借助这个模块我们可以创建项目,而不是直接下载了项目,一定要有所区分。
1.11 是17年开始的,支持时间很长。2.2 也是长期支持的。
2.2 创建一个django项目
下面的命令创建了一个名为"mysite"的Django 项目:
django-admin startproject mysite
2.3 目录介绍
mysite/ ├── manage.py # 管理文件 └── mysite # 项目目录 ├── __init__.py ├── settings.py # 配置 ├── urls.py # 路由 --> URL和函数的对应关系 └── wsgi.py # runserver命令就使用wsgiref模块做简单的web server
2.4 运行Django项目
python manage.py runserver 127.0.0.1:8000
2.5 模板文件配置
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, "template")], # template文件夹位置 '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', ], }, }, ]
2.6 静态文件配置
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), # 静态文件存放位置 ]
看不明白?有图有真相:
刚开始学习时可在配置文件中暂时禁用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', ]
三、Django基础必备三件套
from django.shortcuts import HttpResponse, render, redirect
3.1 HttpResponse
内部传入一个字符串参数,返回给浏览器。
例如:
def index(request): # 业务逻辑代码 return HttpResponse("OK")
3.2 render
除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。
将数据填充进模板文件,最后把结果返回给浏览器。(类似于我们上面用到的jinja2)
例如:
def index(request): # 业务逻辑代码 return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})
3.3 redirect
接受一个URL参数,表示跳转到指定的URL。
例如:
def index(request): # 业务逻辑代码 return redirect("/home/")
四、APP
你会发现,上面没有什么view视图函数的文件啊,这里我们说一个应用与项目的关系,上面我们只是创建了一个项目,并没有创建应用,以微信来举例,微信是不是一个大的项目,但是微信里面是不是有很多个应用,支付应用、聊天应用、朋友圈、小程序等这些在一定程度上都是相互独立的应用,也就是说一个大的项目里面可以有多个应用,也就是说项目是包含应用的,它没有将view放到这个项目目录里面是因为它觉得,一个项目里面可以有多个应用,而每个应用都有自己这个应用的逻辑内容,所以他觉得这个view应该放到应用里面,比如说我们的微信,刚才说了几个应用,这几个应用的逻辑能放到一起吗,放到一起是不是就乱套啦,也不好管理和维护,所以这些应用的逻辑都分开来放,它就帮我们提炼出来了,提炼出来一个叫做应用的东西,所以我们需要来创建这个应用。
通过django命令创建的项目:他认为你的项目我已经给你创建好包含(服务器相关应用以及url等)。但是你的应用逻辑需要自己完成。也就是说咱们的项目中必须创建应用。
4.1 命令行创建
python manage.py startapp app01
4.2 使用PyCharm创建
在下方弹出的命令窗口输入:
startapp app01
我们现在只需要看其中两个文件
models.py :之前我们写的那个名为model的文件就是创建表用的,这个文件就是存放与该app(应用)相关的表结构的
views.py :存放与该app相关的视图函数的
五、基于Django项目实现简单的登录示例
接下来,我们基于Django项目实现一个简单的登录,将整个流程走通。
按照我们之前自己写的起飞版web项目,主要是两部分,服务器程序以及应用程序,在Django项目中服务器程序已经给我们封装好了,基本上学一些参数即可,比较容易,主要是应用程序,所以我们第一步先配置应用程序,应用程序的第一步在哪?启动项目,在浏览器输入ip端口,回车,这样服务端接收到路径根据不同的路径执行对应的函数,所以我们先配置路径url.
5.1 配置url
from app01 import views # 必须引用views模块 urlpatterns = [ # url(r'^admin/', admin.site.urls), 这个路径拼接的admin组件,后面我们会讲到。 url(r'^index/', views.login), ]
这里是通过正则匹配匹配的路径,前面固定拼接的就是'127.0.0.1:8000',现在你这样写'/index/' ,后面映射的就是views.py视图函数的login,因为是正则匹配,所以如果你访问的是这样的路径:'http://127.0.0.1:8000/index/login/666',也是可以映射到此函数的,你要想完全匹配的话应该这样写:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), 这个路径拼接的admin组件,后面我们会讲到。 url(r'^index$', views.login), ] 下面是django2.x版本的url写法,不太一样了,但是兼容1.x的,不过我们现在还是主要说1.xx版本的,所以写url的时候按照上的方式写。 from django.contrib import admin from django.urls import path from app01 import views #找对应的函数,是哪个app里面的函数 from app01 import views urlpatterns = [ path('admin/', admin.site.urls), #这个先不用管,后面会学 path('index/',views.index), ]
这样通过浏览器只能输入http://127.0.0.1:8000/index此url才可以映射到login函数。
5.2 配置views视图函数
找到views文件,定义一个login函数,之前我们自己写的时候可以接受形参envison,现在我们可以设置任意形式参数,一般我们设置为request,request参数就包含了服务器程序的请求响应所有的参数提供给我们使用。
from django.shortcuts import render, HttpResponse def login(request): print(request) # <WSGIRequest: GET '/index'> 这是一个对象 print(request.method) # method方法返回的就是请求方式,本次请求就是get请求 return HttpResponse('跑通了,好玩么?') # 返回给页面一行字符串,一般都是测试是否跑通了。
那么如何返回一个html页面呢? 这里就需要引用另一个功能,就是render。之前jinja2有一个template通过render进行前后端渲染,现在django也给我们提供了一个render方法,可以给浏览器返回一个页面,并且能进行前后端的渲染。我们要完成的就是登录功能,所以我们下面写一个登录页面login.html。现在我们现在views文件中返回。
from django.shortcuts import render, HttpResponse def login(request): return render(request,'login.html') # 第一个参数必须是request参数,因为request包含的是服务器程序的请求与响应所有信息,所以你返回给谁也就是给谁响应都在request里面,第二个参数就是html页面。
5.3、配置template
接下来我们要完善html页面,再此之前我们需要配置一下template的路径,让django可以找到(有的默认已经配置好了)。
在settings文件中配置:
路径配置成功之后,我们写一个登录的页面。
<!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>Bootstrap 101 Template</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <h1>欢迎访问xx系统,请先登录</h1> <form action="/index/" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="password"> 提交:<input type="submit"> </form> </body> </html>
form表单两点注意:
1. action路径 index前面一定要主动加上‘/’,如果你不主动加上/,则最终路径会给你拼接成:http://127.0.0.1:8000/index/index/
2. form表单为什么用post提交数据?
你访问页面以及form表单提交数据都是通过http://127.0.0.1:8000/index此url也就是说都必须执行login函数,如果都是get请求,那么login函数如何区分哪个get是请求页面哪个get是提交数据呢?所以要用post请求提交数据。
5.4、完善views视图函数
之前写的views视图函数我们只完成了返回一个页面的功能,现在不仅是返回页面,我们应该处理post提交的数据,怎么处理?每次请求都是经过此函数,所以我们要对这两次请求加以区分,怎么区分?我们要判断请求方式是get还是post,通过request.method判断即可,那么如何获取提交过来的数据呢?如果是get请求的数据通过request.GET.get获取,如果是post请求的数据通过request.POST.get获取。所以我们views函数这样完成。
def login(request): if request.method == 'POST': print(request.POST) # <QueryDict: {'username': ['taibai '], 'password': ['123']}> username = request.POST.get('username').strip() password = request.POST.get('password').strip() print(username) if username == 'taibai' and password == '123': return HttpResponse('登录成功') else: return HttpResponse('登录失败') else: return render(request, 'login.html')
post提交数据时你们可能会遇到这种情况:
现在只需要做一步,在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', ]
还记得django写视图函数的时候,有一个参数是必须要给的吗,叫做request,如果你是post请求,那么就用request.POST,就能拿到post请求提交过来的所有数据(一个字典,然后再通过字典取值request.POST.get('username'),取出来的就是个字符串,你在那个字典里面看到的是{'username':['taibai']},虽然看着是列表,但是request.POST.get('username')取出来的就是个字符串),通过request.GET就能拿到提交过来的所有数据,而且记着,每一个视图函数都要给人家返回一些内容,用render或者HttpResponse等,其实render里面也是通过HttpResponse来返回内容,不然会报错,错误是告诉你没有返回任何内容:
django认识了,以后我们就按照下面的步骤来学:
1.django的url控制器
2.django的视图
3.django的模板(template)
4.ORM(花的时间比较久)
做一个小总结
目前我们学过的一些参数:
render:返回给浏览器一个html页面,第一个参数一定是request。 HttpResponse:返回给浏览器一个字符串数据。 request 包含请求相应的服务器程序所有信息。 request.method:请求方法,返回大写的GET,POST。 request.POST:post请求的数据,返回一个querydict. request.POST.get('键'):返回对应的值 request.GET: get请求的数据,返回一个querydict. request.GET.get('键'):返回对应的值。