Django框架(二) MTV模型简介

 


MTV模型

Django的MTV分别代表

编写路由#

URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;

你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。路由映射模块,主要完成url与views视图函数的映射。当一个url请求到来时,会按照这个模块中的url地址从上到下进行匹配,如果匹配成功,将执行映射试图中的函数;反之将返回404错误

URLconf的正则字符串参数#

简单配置#

 注意几点:

#设置项是否开启URL访问地址后面不为/跳转至带有/的路径
APPEND_SLASH=True

如果给路径命名了,那么对应的视图函数中,必须按照该命名作为形参

别名#

urlpatterns = [
    url(r'^admin/', admin.site.urls),   #系统生成的映射
    url(r'^reg/$', views.month_views,name='register')

而在访问的静态文件中

当我们后端的路径发生变化时,前端的页面不用改变任何代码,都能够正常访问

路由应用分发#

如果一个网站很多,有很多app应用,那么就需要很多路由分发。如果将所有的路由分发都放在urlconf文件下,這样会使得文件不易于管理,为此,我们可以给每一个app都创建一个urls.py文件,然后再urlconf中的urlpatterns中将该urls.py文件包含进来就行了。

from django.conf.urls import include, url # 导入全局url
urlpatterns = [
    url(r'^blog', include('blog.urls')),   #将访问路径以bug开头的路径分发到app1下的urls.py模块里进行路由映射
]

这样在我们blog-app中的url中,存放所有关于blog的url分发工作。

urlpatterns = [
    url(r'^2004/$', year_2004),     
    url(r'^(\d{4})/$', year_query),     
    url(r'^(\d{4})/(\d{2})$', year_query),     
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})$', year_query),    
]

这样我们访问网站应该是:http://localhost:8080/blog/2012/3  前面都得带上app的名称

编写业务处理逻辑三剑客#

一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。

views.py

注意:视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。

HttpRequest对象#

属性

方法

get_full_path()

注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:

request.POST.getlist("hobby")

request,它是一个对象。
当中存储了请求信息,比如请求路径,请求方式,GET数据,POST数据…等等。
必须要接收一个request参数。
当你想返回一个html文件时,不是使用HttpResponse方法,而是使用render方法来渲染(打包)。
不过本质上render最终还是使用了HttpResponse方法发送byte字节给浏览器的

HttpResponse#

对于HttpRequest请求对象来说,是由django自动创建的,但是,HttpResponse响应对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse响应对象。HttpResponse类在django.http.HttpResponse。

在HttpResponse对象上扩展的常用方法

render(请求对象,'html文件和路径')方法,将指定页面渲染后返回给浏览器

from django.shortcuts import render

def test(request):
    return render(request,'index.html')   #向用户显示一个html页面

render 函数#

下面为render官方源码,可以看出render最后也是返回了一个HttpResponse给webserver

细说render:

render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态文件返回给浏览器。这里一定要注意:render渲染的是模板,下面我们看看什么叫作模板

上面{%%}之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的html文件,浏览器是不能进行渲染的,所以,对于上述{%%}之间的内容先要被render进行渲染之后,才能发送给浏览器。总结一句话就是,render方法作用就是-----填坑

关于render如何填坑,下面举个例子

 

def show(request, id):  
    book = BookInfo.objects.get(pk=id) #从数据库中取出对应id的数据
    herolist = book.heroinfo_set.all()  
    context = {'list': herolist} # 将数据保存在list
    return render(request, 'booktest/show.html', context) #通过render进行模板渲染

render_to_response('html文件和路径')方法,将指定页面渲染后返回给浏览器

from django.shortcuts import render

def test(request):
    return render_to_reponse(request,'index.html')   #向用户显示一个html页面

下面为render_to_reponse源码:

redirect函数#

redirect('跳转路径和名称')方法,页面跳转

from django.shortcuts import render,render_to_response,redirect
def test(request): 
  return redirect('http://www.jxiou.com/') #跳转页面

注意:render与redirect两点区别:

我们来模拟一个登陆网页,当我登陆成功后,跳转到另一个页面,分别用render与redirect来试试。

总结两者区别:    

第一,render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而redirect则不会

第二,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的试图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。

模版层#

python的模板:HTML代码+模板语法

模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签

模板语法: 目的是将变量(数据库的内容)如何巧妙的嵌入到html页面中(就不用之前我们用的字符串拼接了)

在 Django 模板中遍历复杂数据结构的关键是句点字符  .

语法:

{{var_name}}   

view.py

template: 

<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<h4>类对象列表:{{ person_list.0.name }}</h4>

注意:句点符也可以用来引用对象的方法(无参数方法)。

<h4>字典:{{ dic.name.upper }}</h4>

settings.py设置模板文件夹

settings.py文件中有TEMPLATES变量,它是一个列表,列表中又存放了一个字典,其中一个键值对
'DIRS':[os.path.join(BASE_DIR, 'templates')]
效果就是默认设置了模板目录是使用默认的项目文件夹下的templates目录。
如果有特殊需要修改的就是在此改动。
另外django有一个好处,代码更改之后,一般无需重启web服务,它会自动加载最新代码。

使用静态文件#

将html文件返回给用户还不够,前端三大块,HTML、CSS、JS还有各种插件等,完整齐全才是一个好看的页面。在django中,一般将静态文件放在static目录中。接下来,在项目根目录下新建一个static目录。
同时,我还在此目录下建立起js,css,img子目录和相关文件:

static这个静态目录名和Django默认设置的静态目录名别名一致,
在settings.py中可找到相关设置项,就是在结尾处再添加上新的一行表示告诉Django静态目录的路径:

同理,在html文件中引用静态文件,例如jquery.js文件如下:

主要看<script src="/static/js/jquery.js"></script>这一行,里面的路径并没有写死,而是使用了/static/来代指了真实的静态目录

接收用户发送的数据#

至此,我们做到了将一个要素齐全的HTML文件返还给了用户浏览器。
但这还不够,因为web服务器和用户之间还没有动态交互。
下面我们来设计一个login页面,上面建立一个表单,让用户输入用户名和密码,提交给login
这个url,服务器将接收到这些数据。

这其中牵涉到一个csrf的防护机制

CSRF百度百科:CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
假如没有加{% csrf_token %}这一行防护,运行时将会报错

urls.py中urlpatterns添加路由条目:

1
path('login/', views.login),

views.py中添加login函数

此逻辑处理将会在pycharm中可以看到用户输入的用户名密码。

运行效果如下:
html页面效果:

pycharm后端效果:

pycharm中可以看到提交后的post请求数据后端都获取到了

返回动态页面#

我们收到了用户的数据,但返回给用户的依然是个静态页面,通常页面会根据用户的数据,进行处理后在返回给用户。
django采用自己的模板语言,类似jinja2,可根据提供的数据,替换掉HTML中的相应部分。

例:views.py文件修改如下:

而login.html相应修改:

login.html中利用for循环将data(引用)迭代填入数据到表格。

效果就是用户列表会随着提交的数据而发生变化,算是一个简单的动态页面, 和用户的交户过程

使用数据库#

使用mysql的步骤

虽然和用户交互得很好,但并没有保存任何数据,页面一旦关闭,或服务器重启,一切都将回到原始状态。
使用数据库是正常最常见的,django通过自带的ORM框架操作数据库,并且自带轻量级的sqlite3数据库。这次我们先来使用sqlite数据库来演示,后面再学习详细使用mysql。
首先是注册app,不进行这一步的话django不会知道该给哪个app创建表。

在settings.py中注册你的app:

例,因为我之前执行了创建应用的命令,django2.06版本自动在创建应用的同时就帮我注册了app,就是上面代码中的app01.apps.App01Config。如果重复注册一个app01,会在运行python manage.py makemigrations命令的时候报错django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: app01

然后在settings中,配置数据库相关的参数,这次使用自带的sqlite,不需要修改

编辑models.py,也就是MTV中的M

以上创建了三个字段,分别保存id,用户名和密码。

将models中的类映射到数据库中要输入两条命令

第一条命令

1
2
3
python manage.py makemigrations
<br>注:migration翻译为迁移
注意此时运行完此命令只是翻译了了sql语句,还没有真正将sql语句实行到数据库中

运行结果

第二条命令

运行结果

使用sqlite3作为数据库的话,现在可以在项目根目录下看到有db.sqlite3文件

可以使用查看sqlite文件的软件连接查看该数据库验证。

例如使用navicat连接sqlite:

修改views.py中的业务逻辑如下

重启web服务,刷新浏览器页面,之后和用户交互的数据都能保存到数据库中。
任何时候都可以从数据库中读取数据,展示到页面上

 

利用pycharm自带的数据库工具也可以查看和操作数据库,不过要下载对应数据库的驱动

 

这样操作数据库也非常方便

至此,一个要素齐全,主体框架展示清晰的简单django项目完成了,最后分析一下Django的请求生命周期。

Django请求生命周期#

 

补充:什么是根目录

1
就是没有路径,只有域名、。url(r'^$')

补充一张关于wsgiref模块的图片

 

posted @   鲸鱼的海老大  阅读(15)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示
CONTENTS