Django MVT架构

Web框架中的一些概念

MVC

  • 大部分开发语言中都有MVC框架
  • MVC框架的核心思想是:解耦
  • 降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
  • m表示model模型,主要用于对数据库层的封装,对数据库的数据进项各种操作
  • v表示view视图,用于对数据的展示层操作,负责模板页面的展示
  • c表示controller控制器,用于对业务逻辑层操作,用于处理请求、获取数据、返回结果

MVT

  • Django是一款python的web开发框架
  • 与MVC有所不同,属于MVT框架
  • m表示model,负责与数据库交互
  • v表示view,是核心,负责接收请求、获取数据、返回结果
  • t表示template,负责呈现内容到浏览器

Django安装

作为Python Web框架,Django需要Python,在安装Python同时需要安装pip。安装系统环境ubuntu16.04

在线安装Django

pip3 install Django==1.11.*

如果没有安装pip3 

    sudo apt install python3-pip

检测当前是否安装Django及版本

python3 -m django --version

Django入门

一,Django框架的搭建

django安装后 进行django框架的搭建

django-admin startproject mysite

mysite是项目目录名,可以自定义,

我们来看看startproject创建的内容:

tree是linux命令负责将当前文件夹以数状结构显示,
如若提示未找到命令进行 sudo apt-get install tree 即可

yc@yc-virtual-machine:~/test$ tree
.
└── mysite
    ├── manage.py
    └── mysite
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

2 directories, 5 files

关于上面自动生成的目录与文件解释如下

  • 外部test/根目录只是一个项目的容器。它的名字与Django无关; 您可以将其重命名为您喜欢的任何内容。
  • manage.py:一个命令行实用程序,可以让您以各种方式与此Django项目进行交互。你可以阅读所有的细节 manage.py在Django的管理和manage.py。
  • 内部mysite/目录是您的项目的实际Python包。它的名字是您需要用来导入其中的任何内容的Python包名称(例如mysite.urls)。
  • mysite/init.py:一个空的文件,告诉Python这个目录应该被认为是一个Python包。
  • mysite/settings.py:此Django项目的设置/配置。 Django设置会告诉你所有关于设置的工作原理。
  • mysite/urls.py:该Django项目的URL声明; 您的Django动力网站的“目录”。
  • mysite/wsgi.py:WSGI兼容的Web服务器为您的项目提供服务的入口点。

二,启动项目

在当前 manage.py的文件目录下 执行一下命令

sudo python3 manage.py runserver

您将在命令行中看到以下输出:

Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.(注意:现在忽略关于未执行应用数据库迁移的警告)

October 10, 2018 - 15:50:53
Django version 1.11, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

注意:通过IP访问后报如下错误:

DisallowedHost at /polls
Invalid HTTP_HOST header: '192.168.*.*:8000'. You may need to add '192.168.*.*' to ALLOWED_HOSTS.

HTTP_HOST标头无效:'192.168.*.*:8000'。您可能需要将“192.168.*.*”添加到ALLOWED_HOSTS
解决:
进入 mysite/settings.py文件
ALLOWED_HOSTS = ['192.168.194.132']

三,浏览器访问

    在浏览器中 输入 127.0.0.1:8000 进行访问
    
    结果:
    It worked!
    Congratulations on your first Django-powered page.

创建应用

1,创建应用

Django自带一个实用程序,可以自动生成应用程序的基本目录结构,因此您可以专注于编写代码而不是创建目录。

要创建您的应用程序,请确保您与目录位于同一目录,manage.py 并键入以下命令:

python3 manage.py startapp myweb

这将创建一个目录myweb,其目录如下:此目录结构将容纳轮询应用程序。

[root@localhost demo]# tree mysite/
mysite/
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── myweb
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

2,创建视图

Django具有“视图”的概念来封装负责处理用户请求和返回响应的逻辑。

在myweb/views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.

# 定义视图函数,业务逻辑
def index(request):

    # 返回一句话
    return HttpResponse('Hello World!!!')

3,修改root路由 mysite/urls.py

当用户使用django提供的站点进行访问时,首页由路由进行匹配访问地址,然后指定函数或子路由进行处理

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^', include('myweb.urls')),
]

4,在应用下创建子路由,命名为urls.py

及路径为myweb/urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^hello/',views.index),
]

5,通过浏览器访问服务

注意:url路由,由上而下 进行匹配,如果在上面就匹配成功,则不会向下匹配

通过浏览器访问服务
    127.0.0.1:8000/hello/ ==>  root url(根路由) ==> 加载子路由(myweb/urls.py)

    ==> 正则匹配访问的路径(path) =-=> 视图函数(views.index)

    ==> views.py index() 响应内容

6,使用模板

作为Web 框架,Django 需要一种很便利的方法以动态地生成HTML。

最常见的做法是使用模板。

模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。

在当前manage.py的同级目录中创建一个文件夹 templates/index.html

在settings.py文件中 TEMPLATES模块设置选项

'DIRS': [os.path.join(BASE_DIR,"templates")],

在子路由中添加一个路由
url(r'^tmp$',views.tmp,name='myweb_tmp'),

在views.py 创建一个 tmp的视图函数

def tmp(request):
    # 加载一个模块
    return render(request,'index.html')

如果在视图函数加载模板时,分配了数据,就可以在模板中使用数据

def tmp(request):
  # 实例化 模型对象,获取数据

  # 分配数据,
  context = {'info':'aabbccddee'}
  # 加载一个模块
  return render(request,'index.html',context)


在html模板中输出变量 输出 

 <h3>加载数据</h3>
 <p>{{ info }}</p>

URLconf路由

一个干净优雅的URL方案是高质量Web应用程序中的一个重要细节。

Django可以让你设计URL,无论你想要什么,没有框架限制。

要为应用程序设计URL,您可以非正式地创建一个名为URLconf(URL配置)的Python模块。

这个模块是纯Python代码,是一个简单的Python模式(简单的正则表达式)到Python函数(您的视图)之间的映射。

1. Django是如何处理一个请求:

当用户从Django供电的站点请求页面时,系统遵循以下算法来确定要执行的Python代码:

  1. 首先Django确定要使用的根URLconf模块,通过ROOT_URLCONF来设置,具体在settings.py配置文件中。但是如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则其值将用于替换ROOT_URLCONF设置。
  2. Django加载该Python模块并查找该变量 urlpatterns。这应该是一个Python的django.conf.urls.url()实例列表。
  3. Django按顺序运行每个URL模式,并在匹配所请求的URL的第一个URL中停止
  4. 一旦正则表达式匹配,Django将导入并调用给定的视图,这是一个简单的Python函数(或基于类的视图)。
  5. 如果没有正则表达式匹配,或者在此过程中的任何一点出现异常,Django将调用适当的错误处理视图。

示例

以下是一个URLconf示例:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

说明:

  • 要从URL捕获一个值,只需将其括起来
  • 没有必要添加一个主要的斜杠,因为每个URL都有。例如articles,不是/articles。
  • 正则中的'r'正面的每个正则表达式字符串的中是可选的,但推荐使用。它告诉Python一个字符串是“raw” - 字符串中没有任何内容应该被转义。请参阅Dive Into Python的解释。

示例请求:

  • /articles/2005/03/将匹配列表中的第三个条目。Django会调用该函数 。views.month_archive(request, '2005', '03')
  • /articles/2005/3/ 不符合任何网址格式,因为列表中的第三个条目需要两个数字的月份。
  • /articles/2003/将匹配列表中的第一个模式,而不是第二个模式,因为模式是按顺序测试的,第一个模式是第一个测试通过。随意利用这些命令插入特殊情况。在这里,Django会调用该函数 views.special_case_2003(request)
  • /articles/2003 将不匹配任何这些模式,因为每个模式要求URL以斜杠结尾。
  • /articles/2003/03/03/将匹配最终模式。Django会调用该函数。views.article_detail(request, '2003', '03', '03')

注意:每个捕获的参数都作为纯Python字符串发送到视图,无论正则表达式的匹配是什么,即使[0-9]{4}只会匹配整数字符串。

2. 命名组

  • 上述使用为简单实例,属于正则表达式非命名组(通过括号)捕获URL定位,并将它们作为位置参数传递给视图。
  • 在更高级的使用中,我们可以使用正则表达式命名组来捕获URL定位,并将它们作为关键字 参数传递给视图。
  • 在Python正则表达式中,正则表达式命名组的语法是(?P<name>pattern),其中命名组中的命名就是name,并且 pattern是某些匹配的模式。

实例:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

这完成了与上一个例子完全相同的事情,有一个微妙的区别:捕获的值被传递到视图函数作为关键字参数,而不是位置参数

例如:

  • 请求/articles/2005/03/调用函数 ,。views.month_archive(request, year='2005', month='03') 而不是 views.month_archive(request, '2005', '03')
  • 请求/articles/2003/03/03/调用函数 。views.article_detail(request, year='2003', month='03', day='03')
  • 在实践中,这意味着您的URLconfs稍微更明确,更不容易出现参数命令错误 - 您可以重新排序视图的函数定义中的参数。当然,这些好处是以简洁为代价的; 一些开发人员发现命名组语法丑陋而且太冗长。

URLconf的搜索

URLconf将根据所请求的URL进行搜索,作为普通的Python字符串。这不包括GET或POST参数或域名。

例如:

URLconf不查看请求方法。换句话说,所有的请求方法(GET,POST,HEAD等)都将被路由到相同的URL功能。

指定用于视图参数的默认值

一个方便的技巧是为您的视图参数指定默认参数。下面是一个URLconf和view的例子:

在下面的示例中,两个URL模式指向相同的视图views.page- 但是第一个模式不会从URL捕获任何内容。

如果第一个模式匹配,该page()函数将使用它的默认参数num,"1"。

如果第二个模式匹配, page()将使用num正则表达式捕获的任何值。

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

3. 错误处理

当Django找不到与请求的URL匹配的正则表达式时,或者异常引发时,Django将调用错误处理视图。

用于这些情况的视图由四个变量指定。它们的默认值对于大多数项目都是足够的,但通过覆盖其默认值可以进一步定制。

有关详细信息,请参阅自定义错误视图的文档。

这样的值可以在你的根URLconf中设置。在任何其他URLconf中设置这些变量将不起作用。

值必须是可调用的,或者代表视图的完整的Python导入路径的字符串,应该被调用来处理手头的错误条件。

变量是:

  • handler400- 见django.conf.urls.handler400。
  • handler403- 见django.conf.urls.handler403。
  • handler404- 见django.conf.urls.handler404。
  • handler500- 见django.conf.urls.handler500。

关于404错误

  • 404的错误页面,在模板目录templates中创建一个404.html的页面
  • 在配置文件中 settings.py DEBUG=False
  • 在出现404的情况时,自动寻找404页面。
  • 也可以在视图函数中 手动报出404错误,带提醒信息

在视图函数中也可以指定返回一个404

注意 Http404需要在django.http的模块中引入
from django.http import Http404
def index404(request):
    raise Http404('纳尼')
    return HttpResponse('Hello World')

在模板中 404.html

<!DOCTYPE html>
<html>
<head>
    <title>404</title>
</head>
<body>
    <center>
        <h2>404 not found</h2>
    </center>
</body>
</html>

4. 包括其他的URLconf

在任何时候,您urlpatterns都可以“包含”其他URLconf模块。

这实质上是将一组网址“植根于”其他网址之下

例如,下面是Django网站本身的URLconf的摘录。它包含许多其他URLconf:

from django.conf.urls import include, url

urlpatterns = [
    # ... snip ...
    url(r'^community/', include('django_website.aggregator.urls')),
    url(r'^contact/', include('django_website.contact.urls')),
    # ... snip ...
]

请注意,此示例中的正则表达式没有$(字符串尾匹配字符),但包含尾部斜线。

每当Django遇到include()django.conf.urls.include())时,它会截断与该点匹配的URL的任何部分,并将剩余的字符串发送到包含的URLconf以供进一步处理。

5. URL的反向解析

如果在视图、模板中使用硬编码的链接,在urlconf发生改变时,维护是一件非常麻烦的事情

  • 解决:在做链接时,通过指向urlconf的名称,动态生成链接地址

  • 视图:使用django.core.urlresolvers.reverse()函数

  • 模板:使用url模板标签

        #给路由起个名
        url(r'^goods/lists/$', views.goodslist,name="goods_list"),
    
        在使用指定路径时,就可以通过 路由名字来动态解析 路由的地址
        <a href="{% url 'goods_list' %}">跳转到商品列表页</a>
    
        在html的模板中使用 模板标签来解析路由规则 {% url 'name' %}
    
        在视图函数中 reverse() 进行反向解析
        from django.core.urlresolvers import reverse
        # 反向解析
        res = reverse('goods_list')
        print(res)
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容