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.pyviews.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)相关推荐

  1. Django项目实战——用户投票系统(三)

    Django项目实战--用户投票系统(三) 承接上文 官方文档链接附上: 编写你的第一个 Django 应用,第 3 部分 | Django 文档 | Django (djangoproject.co ...

  2. Django项目实战:CMDB资产扫描和DevOPS自动化运维

    文章目录 项目实战:CMDB自动化资产扫描和自动化运维 1.项目介绍 2.项目技术分析 运维自动化难点和痛点 项目技术难点 整体工程设计 3.项目环境搭建 项目环境要求 项目环境的搭建 项目目录的配置 ...

  3. python django项目实例_最新Django项目实战-从零开发NB的任务平台python视频学习教程...

    saas导学视频 .mp4 │ 模态框.zip │ ├─day01 │ │ 01 day01 sass项目介绍 .mp4 │ │ 02 day01 sass项目演示 .mp4 │ │ 04 day01 ...

  4. Django项目实战: Django + PyPDF2实现PDF页面提取和PDF文件输出

    在日常工作中我们经常需要从一个大的PDF文档中提取我们所需要的页面,所以今天我们将教你用Django + PyPDF2开发个小Web应用: 用户上传一个PDF文档,输入需要提取的页面号码,点击确定后浏 ...

  5. Django项目实战(一)项目准备

    今天开始将更新Django项目专栏,此次项目是电商项目,具体页面效果等最后完成时更新,有需要的朋友可以点个关注哦! 开发模式 选项 技术选型 开发模式 前后端不分离 后端框架 Django 前端框架 ...

  6. django项目实战(2)-数据库配置

    2019独角兽企业重金招聘Python工程师标准>>> 项目创建完成后,我们需要配置数据库了,虽然我们在创建项目的时候选择了mysql数据库,但是我们还要安装MySQL_python ...

  7. Django项目实战——6—(退出登录、判断用户是否登录、QQ登录、QQ登录工具QQLoginTool、本机绑定域名)

    1.退出登录 注册界面跳转到登陆界面:templates/register.html 前端注册界面 {# 跳转到登陆界面 #}<a href="{% url 'users:login' ...

  8. Django项目实战——8—(判断用户是否登录并返回JSON、Django发送邮件的配置、生成邮箱验证链接、验证邮箱后端逻辑)

    1.判断用户是否登录并返回JSON 重要提示: 只有用户登录时才能让其绑定邮箱. 此时前后端交互的数据类型是JSON,所以需要判断用户是否登录并返回JSON给用户. 方案一: 使用Django用户认证 ...

  9. Django项目实战——14—(列表页热销排行、商品搜索、Haystack建立数据索引、渲染商品搜索结果、商品详情页)

    1.列表页热销排行 根据路径参数category_id查询出该类型商品销量前二的商品. 使用Ajax实现局部刷新的效果. 查询列表页热销排行数据 请求方式 请求参数:路径参数 响应结果:JSON {& ...

  10. Django项目实战——5—(用户登录、首页用户名展示、项目阶段总结)

    1.用户登录 用户名登录逻辑分析 用户名登录接口设计 请求方式 请求参数:表单 响应结果:HTML 用户名登录逻辑实现 用户后端验证视图文件apps/users/views.py "&quo ...

最新文章

  1. CentOS 7.0系统安装配置图解教程
  2. 2021高考成绩查询是几点,2021高考查分是从几点到几点
  3. 查看springboot中tomcat版本
  4. 以mips为单位衡量微型计算机的性能,2016计算机二级《MS Office》选择题专项训练...
  5. java位运算实例详解——(amp;)、(|)、(~)、(^)、(lt;lt;)、(gt;gt;)
  6. 深入浅出Java多线程
  7. codevs2171 棋盘覆盖
  8. 为什么跨境电商独立站将成为几年的焦点?
  9. Spring的ID增长器使用示例(MySql数据库)
  10. WWW'22 | 信息检索方向值得一读的3篇论文详解
  11. Linux chmod命令 修改文件权限被禁止(not permitted)的解决办法
  12. 无卡时代存取款的N种姿势:刷脸、扫码、手机Pay
  13. 百度火星坐标转wgs84
  14. 怎么给计算机上锁键盘,想把笔记本电脑的键盘锁住,用外置键盘怎样做?
  15. BH1750FVI光强度传感器及其STM32驱动程序
  16. 飞线(jump wire)
  17. git原理学习记录:从基本指令到背后原理,实现一个简单的git
  18. android课程设计健身,健身软件课程设计_毕业论文设计.doc
  19. Mysterious Organization
  20. 减少用户投诉,就选中国移动二次号查询

热门文章

  1. BT下载4K电影、视频
  2. 3V升压5V芯片,3V升压5V的电路图
  3. 北理珠大学生体质测试及健康状况的分析
  4. python数据挖掘的基本流程有哪些?
  5. linux dos2unix用法,Linux命令之dos2unix
  6. Android单机游戏保存进度,安卓游戏存档修改教程 | 手游网游页游攻略大全
  7. 重学Java 8新特性 | 第1讲——我们为什么要学习Java 8新特性?
  8. 计算机中丢失d3dx11 43.dll,电脑为何玩了游戏都有什么丢失d3dx11_34.dll
  9. VMware安装win10:需win10虚拟机专用镜像,不是真机装系统的ISO镜像
  10. TCL语言学习笔记一