Django项目实战(1)
Django项目实战
- Django
- Django中请求处理流程
- 理解视图(views):业务逻辑的编写
- 编写第一个视图
- 将视图接入路由(view.py-->urils.py)
- 理解模板:网页前端的实现
- Django模板语言基础
- 表达式插值
- 条件语句
- 循环语句
- 理解模型(model):和数据库的联动
- 理解ORM
- 理解数据库迁移
- 实现第一个数据模型
- 配置后台管理接口
- URL调度过程实例
- 开始第一个Demo
Django
从今天开始进行Django项目的实战系列更新,希望这系列笔记,能给帮助到和我一样正在学习路上的你和我!
Django中请求处理流程
因为之前没有Web开发的经验,本身也是转行到计算机这个领域中来,之前也折腾过很长的时间,视频教程、博客、国内的书籍等等,各有利弊,所以这几天看了一些国外的书籍,国外的书籍相比较于国内的更新速度更快,这是很大的一个优点,再就是觉得还是看书比较的系统掌握像Django这样的框架,高屋建瓴的了解一些思想、逻辑会有助于理解框架的代码细节。
这里先回忆昨天学习的成果。相比较于Java Spring全家桶的开发工作来说,Django的开发工作明显较少,很多事情Django都已经帮助你完成了,因此开发速度快速,但是对于大型服务系统来说,是不是鲁棒性会差一点??(这里还不是很懂,请大家指教)
1、 用户通过浏览器请求一个页面(上传数据、点击访问等等)
2、请求到达Request Middlewares,中间件对request做一些预处理或者直接response请求
3、URLConf通过urls.py文件和请求的URL找到相应的View()
4、View Middlewares被访问,它同样可以对request做一些处理或者直接返回response
5、调用View中的函数
6、View中的方法可以选择性的通过Models访问底层的数据
7、所有的Model-to-DB的交互都是通过manager(QuerySet)完成的
8、如果需要,Views可以使用一个特殊的Context
9、Context被传给Template用来生成页面
a.Template使用Filters和Tags去渲染输出
b.输出被返回到View
c.HTTPResponse被发送到Response Middlewares
d.任何Response Middlewares都可以丰富response或者返回一个完全不同的response
e.Response返回到浏览器,呈现给用户
可以从流程图中看出Middleware(中间件,包括request、view、exception、response)发挥了很重要的作用,这里暂未涉及,先不讨论。
参考:https://www.cnblogs.com/lyq-biu/p/9626234.html、https://segmentfault.com/a/1190000002399134
URLConf(URL映射):就像是Django所支撑网站的目录。本质是URL模式以及要为该URL模式调用的视图函数(view)之间的映射表。就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。例如,当用户访问/foo
时,调用视图函数foo_view()
,视图函数存在于views.py
中。
在执行创建项目的时候,会自动创建一个URLConf(就是项目的urls.py)。在同时创建的settings.py
文件中,还有一个变量ROOT_URLCONF
,其变量的值就是根(项目文件夹下的)URLconf的模块名。默认值是urls.py
文件的模块名。
###Django application组织原则
实际上,每个 Django App(Application) 的组织结构符合 Django 的 MTV 法则——Model (模型)+ Template (模板)+ View (视图)。MTV 与大家比较熟悉的 MVC 在思想上非常相似,但是命名有比较大的出入,如下表所示:
区别:
MVC中的View的目的是「呈现哪一个数据」,而MTV的View的目的是「数据如何呈现」。
也就是把MVC中的View分成了视图(展现哪些数据) 和 模板(如何展现) 2个部分,而Contorller这个要素由框架自己来实现了,我们需要做的就是把(带正则表达式的)URL对应到视图就可以了,通过这样的URL配置,系统将一个请求发送到一个合适的视图。
https://www.cnblogs.com/wqzn/p/10009217.html、https://blog.csdn.net/YangHeng816/article/details/52213983
理解视图(views):业务逻辑的编写
创建Application之后,下一步就是编写业务逻辑和接入路由,完成访问了。
如前所述Django中的Project目录和application目录下分别有urls.py
文件
分别负责不同的功能:
一个是全局路由,一个是子应用路由组成。简单来说,根据用户输入的 URL,全局路由表进行匹配并选择正确的子应用路由,再由所选择的子应用路由匹配并选择正确的视图( View )。整个流程如下图所示:
例如,用户访问 example.com/apple/buy
,然后全局路由根据 /apple/buy
先选择 apple
的路由表,再从 apple
路由表中根据 /buy
选择 /buy
路由,然后执行 /buy
对应的 BuyView
视图,返回给用户结果。
编写第一个视图
首先打开 news/views.py
,写一个简单的视图函数,返回一串 Hello World!
from django.http import HttpResponsedef index(request):return HttpResponse('Hello World!')
上面这个 index 函数可以说是一个最简单的视图函数了,实际大部分应用的视图要比这复杂得多。Django 同时支持基于函数的视图
( FBV,Function-based View )和基于类的视图
( CBV,Class-based View ),这里显然是 FBV,接收一个 request 请求对象作为参数,返回了一个 HttpResponse 对象。
将视图接入路由(view.py–>urils.py)
接着,我们要让路由系统能够访问到刚才写好的视图函数。因此先实现子应用news
的路由表,创建 news/urls.py
文件如下:
from django.urls import path
from . import views
urlpatterns = [path('', views.index, name='index'),
]
每一个 Django 路由表模块( urls.py
)中都约定必须包含一个 urlpatterns
列表用来存放路由映射表。列表中每个元素是一个用 django.urls.path
函数封装好的路由映射,通常接收以下三个参数:
- route:必须,即实际的访问路由,空字符串等于 /,即空路由
- view:必须,该路由将要访问的视图(重要参数)
- name:可选,该路由的名称,方便后续在模板中使用
我们将刚刚写好的 news
路由表接入全局路由表。由于我们希望新闻能够展示在首页(即通过 /
就能访问,无需/news
),因此 news
应用路由在全局路由中的 URL 是一个空字符串。在 django_news/urls.py
中修改如下:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),## route为空字符串path('', include('news.urls')),
]
这里使用django.urls.include
函数将 news
应用的路由表接入进来,并且 include
函数的参数是路由模块路径的字符串news.urls
,省去了手动 import 的麻烦(写法并不规范,不要学习此示例写法。这里记录的目的是为了学习Django流程化的开发思路)。
注意
添加路由规则时顺序是很重要的,因为在尝试匹配时会按照从上到下的顺序进行,因此应该把最模糊的路由(即空路由)放在最下面。
现在已经完成了一个非常简单的demo开发工作。
理解模板:网页前端的实现
想想前面我们做了什么?我们首先定义了view(视图)、定义了urls.py(主路由和子应用路由),完成了一次访问配置。接下来,我们将实现一个 Django 模板作为网页前端,从而给用户呈现更丰富的内容。
Django模板语言基础
表达式插值
最常用的语法,没有之一。通过在一对花括号{{}}
放入一个表达式,就能够在视图(views)中传入表达式中变量的内容,并最终渲染成包含变量具体内容的 HTML 代码。需要注意的是,所支持的表达式仅支持以下形式(可以自由组合):
<!-- 单个变量 -->
{{ variable }}<!-- 获取字典的键或对象的属性 -->
{{ dict.key }}
{{ object.attribute }}<!-- 获取列表中的某个元素 -->
{{ list.0 }}
例如,模板这样写:
<h1>{{ name }}</h1>
<p>{{ news.title }}</p>
<p>{{ news.visitors.0 }}</p>
如果我们在视图中(view)传入以下上下文字典( Context Dictionary ):
{'name': 'Tuture','news': {'title': 'Hello World','visitors': ['Tom', 'Marc'],}
}
那么最终渲染成的HTML代码就是:
<h1>Tuture</h1>
<p>Hello World</p>
<p>Tom</p>
条件语句
条件语句的定义如下:
{% if is_true %}<h1>It is true!</h1>
{% else %}<h1>It is false!</h1>
{% endif %}
如果变量 is_true
为真,那么最终渲染出来的就是 <h1>It is true!</h1>
,否则就是 <h1>It is false!</h1>
。注意:整个条件语句必须以 {% endif %}
结束,并且 {% else %}
是可选的。
循环语句
https://v2ex.com/t/663675
理解模型(model):和数据库的联动
- 由于高度解耦的设计,可轻松切换各种关系型数据库(默认的 SQLite,可选 MySQL 、PostgreSQL 、Oracle 等等)
- 强大的 ORM ( Object Relation Mapping,对象关系映射)模块,使得用 Python 操作数据库非常轻松,免去了使用 SQL 的麻烦
- 优秀的数据库迁移机制( Migration ),修改数据模式( Schema )比较方便,能够适应不断变化的功能需求
理解ORM
简单来说,ORM 能够将面向对象的代码转换成相应的 SQL 语句,从而对数据库进行操作。SQL 是用于访问和处理数据库的标准的计算机语言,但是直接写在代码里面显然难以维护,而且对使用者的要求也非常高,写的糟糕的 SQL 代码查询效率非常低下。因此,使用设计良好的 ORM 不仅让代码可读性更好,也能帮助开发者进行查询优化,节省不少力气。
优点:1、操作简单,使用python代码即可维护数据库
缺点:ORM模式笨重,不支持非关系型数据库
理解数据库迁移
数据库迁移是指将用 Django
定义的模型转换成 SQL
代码(即迁移文件),并在数据库中进行建表操作(或更新表)。看下面这张图就知道了:
一般的开发流程就是这样:
1、用 Django 定义了一个新的数据模型
2、用 makemigrations 命令创建迁移文件(存储在子应用的 migrations 目录里面)
3、用 migrate 命令执行迁移
4、在开发中发现第 1 步中定义的模型不完善,更新数据模型
5、跳转到第 2 步,反复循环
实现第一个数据模型
终于到了动手的环节。我们首先定义数据模型 Post ,包括标题 title 字段和 content 字段,代码如下:
from django.db import modelsclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()def __str__(self):return self.title
随后就是创建迁移文件并完成迁移(makemigrations&&migrate
)。
配置后台管理接口
还需要在admin.py
中完成application的注册。
from django.contrib import admin
from .models import Post
admin.site.register(Post)
这是一篇博客介绍,从这里主要学习Django流程上的开发思路,可以看出主要是model.py
、views.py
部分比较复杂一些。
URL调度过程实例
代码示例
#1. mysite.urls.py
from django.conf.urls import patterns, include, urlurlpatterns = patterns('',url(r"^$","mysite.views.index"),url(r"^about/","mysite.views.about"),url(r"^people/",include(people.urls)),url(r"^contact/","mysite.views.contact"),url(r"^update/","mysite.views.update"),
)
#2.people.urls.py
from django.conf.urls import patterns, include, urlurlpatterns = patterns('',url(r"^daoluan/","people.views.daoluan"),url(r"^sam/","people.views.sam"),url(r"^jenny/","people.views.jenny"),
)
#3.people.views.py
def daoluan(request):return HttpResponse("hello")
当我们访问http://example.com/people/daoluan/
的时候URL dispatcher的调度过程(蓝色部分):
1.BaseHandler.get_response()
中根据settings.py
中的ROOT_URLConf
设置选项构造RegexURLResolver
对象,并且调用RegexURLResolver.resolve("/people/daoluan/")
启动解析,其中RegexURLResolver.regex="^\"
,也就是说它会过滤"",url变为"people/daoluan/"
;
2.resolve()
函数中调用RegexURLResolver.url_patterns()
,加载了所有的匹配信息如下(与图中一样):
- (类型)RegexURLPattern(正则表达式) [^$]
- RegexURLPattern [^about/]
- RegexURLResolver [^people/]
- RegexURLPattern [^contact/]
- RegexURLPattern [^update/]
语句 for pattern in self.url_patterns:
开始依次匹配. 第一个因为是 RegexURLPattern
对象, 调用 resolve()
为 RegexURLPattern.resolve()
: 它直接用 [\^$]
去匹配 “people/daoluan/”, 结果当然是不匹配.
3. 下一个pattern过程同上
4. 第三个 pattern 因为是 RegexURLResolver
对象, 所以 resolve()
调用的是 RegexURLResolver.resolve()
, 而非上面两个例子中的 RegexURLPattern.resolve()
. 因为第三个 pattern.regex = "^people/"
, 所以会将 "people/daoluan/"
过滤为 "daoluan/"
. pattern.resolve()
中会调用 RegexURLResolver.url_patterns()
, 加载了所有的匹配信息如下(和图中一样):
- RegexURLPattern [^daoluan$]
- RegexURLPattern [^sam$]
- RegexURLPattern [^jenny$]
语句 for pattern in self.url_patterns
: 开始依次匹配. 第一个就中, 过程和刚开始的过程一样. 因此构造 ResolverMatch
对象返回. 于是 BaseHandler.get_response()
就顺利得到 ResolverMatch
对象, 其中记录了有用的信息. 在 BaseHandler.get_response()
中有足够的信息让你知道开发人员在 views.py
中定义的函数是 def daoluan(request):
在什么时候调用的:
# BaseHandler.get_response() 的定义
# 处理请求的函数, 并返回 response
def get_response(self, request):......# 实例化 RegexURLResolver, 暂且将其理解为一个 url 的匹配处理器, 下节展开resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)......# 调用 RegexURLResolver.resolve(), 可以理解为启动匹配的函数; 返回 ResolverMatch 实例resolver_match = resolver.resolve(request.path_info)......# resolver_match 对象中存储了有用的信息, 譬如 callback 就是我们在 views.py 中定义的函数.callback, callback_args, callback_kwargs = resolver_match......# 这里调用的是真正的处理函数, 我们一般在 view.py 中定义这些函数response = callback(request, *callback_args, **callback_kwargs)......return response
总结:url
调度器主要 RegexURLResolver
, RegexURLPattern
, ResolverMatch
和三个辅助函数 url()
, include()
, patterns()
完成. 可以发现, url 的调度顺序是根据 urls.py
中的声明顺序决定的, 意即遍历一张表而已, 有没有办法提高查找的效率?(https://www.cnblogs.com/daoluanxiaozi/p/3323352.html、http://www.nowamagic.net/academy/detail/13281030#)
再就是Template(模板),Django中的模板不支持直接写Python代码,只支持写template filter、template flag等。可以使用jinja2进行扩展。
问题
1.project下面有一个urls.py,每个application下面也有一个urls.py,这里衍生出一个问题,两个urls.py有什么作用?分别是做什么的?
参见:https://stackoverflow.com/questions/58554737/what-are-the-differences-between-urls-py-in-projects-folder-and-app-folder-in-d
简单来说就是:project下的urls.py
是"基础"路由,例如访问0.0.0.0/blog/1.html
时,会先把请求交给blog application的路由,再根据1.html
在blog application的urls.py
下找打特定的请求地址。
# project's urls.pyfrom django.contrib import admin
from django.urls import include, pathurlpatterns = [path('admin/', admin.site.urls),path('myapp/', include("myapp.urls")) # requests on a route starting with "myapp/" will be forwarded to "myapp.urls"
]
# myapp's urls.py
from django.urls import path
from . import viewsapp_name = "myapp"urlpatterns = [path("", views.index, name="index"),path("contact/", views.contact, name="contact")
]
例如,如果我请求“localhost:8000/myapp/contact”,您的project的urls.py将检测到它必须将该请求转发到您的application–>myapp,而应用程序myapp将调用它的view .contact
。
开始第一个Demo
使用下面的命令创建一个名为mysite的项目
django-admin startproject mysite
可以看到以下形式的目录结构:
这里的manage.py
是一个用于与项目交互的命令行实用程序。它是对django-admin.py工具的简单封装。不需要对这个文件进行任何的修改。
- mysite/:
- _init_.py:一个空文件,用来让Python知道把mysite目录作为Python的一个module。
- asgi.py:这是作为ASGI运行项目的配置,ASGI是用于异步web服务器和应用程序的新兴标准。
- settings.py:包含了初始默认的项目设置和配置
- urls.py:这是URL patterns所在的位置。这里定义的每一个URL都映射到一个view。
- wsgi.py:这是作为Web Server Gateway interface(WSGI)应用程序运行项目的配置。
生成的settings.py
文件包含项目设置,包括一个使用SQLite3
数据库的基本配置和一个名为INSTALLED_APPS
的列表,其中包含默认添加到项目中的常见Django应用程序。我们将在稍后的Project settings
部分介绍这些应用程序。
Django项目实战(1)相关推荐
- Django项目实战——用户投票系统(三)
Django项目实战--用户投票系统(三) 承接上文 官方文档链接附上: 编写你的第一个 Django 应用,第 3 部分 | Django 文档 | Django (djangoproject.co ...
- Django项目实战:CMDB资产扫描和DevOPS自动化运维
文章目录 项目实战:CMDB自动化资产扫描和自动化运维 1.项目介绍 2.项目技术分析 运维自动化难点和痛点 项目技术难点 整体工程设计 3.项目环境搭建 项目环境要求 项目环境的搭建 项目目录的配置 ...
- python django项目实例_最新Django项目实战-从零开发NB的任务平台python视频学习教程...
saas导学视频 .mp4 │ 模态框.zip │ ├─day01 │ │ 01 day01 sass项目介绍 .mp4 │ │ 02 day01 sass项目演示 .mp4 │ │ 04 day01 ...
- Django项目实战: Django + PyPDF2实现PDF页面提取和PDF文件输出
在日常工作中我们经常需要从一个大的PDF文档中提取我们所需要的页面,所以今天我们将教你用Django + PyPDF2开发个小Web应用: 用户上传一个PDF文档,输入需要提取的页面号码,点击确定后浏 ...
- Django项目实战(一)项目准备
今天开始将更新Django项目专栏,此次项目是电商项目,具体页面效果等最后完成时更新,有需要的朋友可以点个关注哦! 开发模式 选项 技术选型 开发模式 前后端不分离 后端框架 Django 前端框架 ...
- django项目实战(2)-数据库配置
2019独角兽企业重金招聘Python工程师标准>>> 项目创建完成后,我们需要配置数据库了,虽然我们在创建项目的时候选择了mysql数据库,但是我们还要安装MySQL_python ...
- Django项目实战——6—(退出登录、判断用户是否登录、QQ登录、QQ登录工具QQLoginTool、本机绑定域名)
1.退出登录 注册界面跳转到登陆界面:templates/register.html 前端注册界面 {# 跳转到登陆界面 #}<a href="{% url 'users:login' ...
- Django项目实战——8—(判断用户是否登录并返回JSON、Django发送邮件的配置、生成邮箱验证链接、验证邮箱后端逻辑)
1.判断用户是否登录并返回JSON 重要提示: 只有用户登录时才能让其绑定邮箱. 此时前后端交互的数据类型是JSON,所以需要判断用户是否登录并返回JSON给用户. 方案一: 使用Django用户认证 ...
- Django项目实战——14—(列表页热销排行、商品搜索、Haystack建立数据索引、渲染商品搜索结果、商品详情页)
1.列表页热销排行 根据路径参数category_id查询出该类型商品销量前二的商品. 使用Ajax实现局部刷新的效果. 查询列表页热销排行数据 请求方式 请求参数:路径参数 响应结果:JSON {& ...
- Django项目实战——5—(用户登录、首页用户名展示、项目阶段总结)
1.用户登录 用户名登录逻辑分析 用户名登录接口设计 请求方式 请求参数:表单 响应结果:HTML 用户名登录逻辑实现 用户后端验证视图文件apps/users/views.py "&quo ...
最新文章
- CentOS 7.0系统安装配置图解教程
- 2021高考成绩查询是几点,2021高考查分是从几点到几点
- 查看springboot中tomcat版本
- 以mips为单位衡量微型计算机的性能,2016计算机二级《MS Office》选择题专项训练...
- java位运算实例详解——(amp;)、(|)、(~)、(^)、(lt;lt;)、(gt;gt;)
- 深入浅出Java多线程
- codevs2171 棋盘覆盖
- 为什么跨境电商独立站将成为几年的焦点?
- Spring的ID增长器使用示例(MySql数据库)
- WWW'22 | 信息检索方向值得一读的3篇论文详解
- Linux chmod命令 修改文件权限被禁止(not permitted)的解决办法
- 无卡时代存取款的N种姿势:刷脸、扫码、手机Pay
- 百度火星坐标转wgs84
- 怎么给计算机上锁键盘,想把笔记本电脑的键盘锁住,用外置键盘怎样做?
- BH1750FVI光强度传感器及其STM32驱动程序
- 飞线(jump wire)
- git原理学习记录:从基本指令到背后原理,实现一个简单的git
- android课程设计健身,健身软件课程设计_毕业论文设计.doc
- Mysterious Organization
- 减少用户投诉,就选中国移动二次号查询
热门文章
- BT下载4K电影、视频
- 3V升压5V芯片,3V升压5V的电路图
- 北理珠大学生体质测试及健康状况的分析
- python数据挖掘的基本流程有哪些?
- linux dos2unix用法,Linux命令之dos2unix
- Android单机游戏保存进度,安卓游戏存档修改教程 | 手游网游页游攻略大全
- 重学Java 8新特性 | 第1讲——我们为什么要学习Java 8新特性?
- 计算机中丢失d3dx11 43.dll,电脑为何玩了游戏都有什么丢失d3dx11_34.dll
- VMware安装win10:需win10虚拟机专用镜像,不是真机装系统的ISO镜像
- TCL语言学习笔记一