Django学习笔记
Django概述
Django是一个高级的Python Web框架,它遵循MVC模式,具有开发快捷、低耦合、部署方便、可重用性高和维护成本低等显著特点。Django负责处理网站开发中麻烦的部分,允许开发者专注于编写应用程序。它提供了强大的数据库抽象层,通过ORM(对象关系映射)可以方便地与不同类型的数据库交互。此外,Django还自带了灵活且强大的管理后台,可以快速生成和管理数据库模型的CRUD操作。Django的安全性也非常出色,内置了防止常见安全漏洞的机制。Django非常适合用于构建大型复杂的Web应用,如内容管理系统、电子商务网站、社交网络网站等。
MVC框架
M:Model(模型) V:Veiw(视图) C: Controller(控制器)
MVC框架的工作原理:
- 当用户在浏览器中实现一个注册时,首先时将注册的信息提交到服务器,有C来接受数据并处理
- 随后C将数据通过M来将注册信息存储到数据库
- 数据库将保存的信息返回给M
- M再将这些信息给到C
- C再把这些信息给到V来产生一个页面返回
- 最终C再把这个页面返回到浏览器,浏览器再显示页面
大致就如下图所示:
MVT框架
M:Model(模型):这部分与MVC中的Model是相似的。它负责处理数据,通常与数据库进行交互。
V:Veiw(视图):在MVT中,Veiw并不是直接等同于MVC中的Controller,
- 在MVC中,Controller负责处理用户输入,更新模型,并选择适当的视图来显示。但在MVT中,View更接近于MVC中View的职责,即负责数据的展示和渲染。
- 在MVT中,View通常不直接处理用户输入或逻辑处理,这些任务通常由其他部分(如Django中的URL配置和视图函数)来完成
T:Template(模板):在MVT中替代了MVC中的View角色。模板定义了数据的展示方式,即用户界面的具体布局和样式。
(一)创建一个Django项目
通过命令:django-admin startproject mybookproject
:
此时在当前的目录下会出现一个基于Django的项目文件夹:mybookproject
,该项目文件中会存放:
mybookproject\
__init__.py
settings.py
urls.py
wsgi.py
manage.py
根据官方对这些文件的解释是:
- 对于外层的
mybookproject
目录仅仅是项目的一个容器。它的命名对Django无关紧要;你可以把它重新命名为任何你喜欢的名字。 - 对于内层的
mybookproject
是你的项目的真正的Python包。它是你导入任何东西时将需要使用的Python包的名字。 mybookproject/__init__.py
:一个空文件,它告诉Python这个目录应该被看做一个Python包。mybookproject/settings.py
:该Django 项目的设置/配置。Django 设置 将告诉你这些设置如何工作。mybookproject/urls.py
:该Django项目的URL声明;你的Django站点的“目录”。mybookproject/wsgi.py
:用于你的项目的与WSGI兼容的Web服务器入口。manage.py
:一个命令行工具,可以使你用多种方式对Django项目进行交互。
(二)创建应用
项目和应用之间有什么不同? 应用是一个Web应用程序,它完成具体的事项 —— 比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用。 项目是一个特定网站中相关配置和应用的集合。一个项目可以包含多个应用。一个应用可以运用到多个项目中去。
进入到django项目目录,随后我们通过命令:python manage.py startapp mybookapp
来构建一个应用目录,我们会在当前文件夹看到这个目录,目录中会存放:
mybookapp\
__init__.py
admin.py
models.py
tests.py
views.py
【这些文件的作用在后面的应用中逐步记录解释】
此时当前的目录结构为:
mybookproject\
__init__.py
settings.py
urls.py
wsgi.py
mybookapp\
__init__.py
admin.py
models.py
tests.py
views.py
manage.py
这个时候我们需要到setting.py中注册该app,告诉django项目,mybookapp这个app已经安装【在INSTALLED_APPS中添加app的名称】:
默认情况下,INSTALLED_APPS包含下面的应用,它们都是Django 与生俱来的:
- django.contrib.admin —— 管理站点。你将在本教程的第2部分使用到它。
- django.contrib.auth —— 认证系统。
- django.contrib.contenttypes —— 用于内容类型的框架。
- django.contrib.sessions —— 会话框架。
- django.contrib.messages —— 消息框架。
- django.contrib.staticfiles —— 管理静态文件的框架。
这些应用,默认包含在Django中,以方便通用场合下使用。
(三)ORM框架
ORM框架即对象关系映射框架
(Object-Relational Mapping),是一种解决面向对象与关系数据库存在互不匹配的现象的技术。它实现了对象和关系型数据库之间的数据交互问题的解决方案的一种规范。
O:Object(对象-类) R:Relations(关系) M:Mapping(映射)
下面展现出了了ORM框架的一个用法:
(四)创建模型
当编写一个数据库驱动的Web应用时,第一步就是定义该应用的模型 —— 本质上,就是定义该模型所对应的数据库设计及其附带的元数据。
模型指出了数据的唯一、明确的真实来源。 它包含了正在存储的数据的基本字段和行为。
我们可以在models.py中编写模型类:
- 在模型的设计中,我们创建了一个类使其继承
models.Model
从而变成一个数据库模型类 - 在这个模型类中,定义了两个类型的字段:字符类型(制定了最大长度为20)、时间类型
这样一个模型就创建好了,随后我们需要生成一份迁移文件,再通过迁移文件将数据迁移到数据库,通过运行makemigrations告诉Django,已经对模型做了一些更改并且会将这些更改记录为迁移文件。迁移是 Django 如何储存模型的变化。
我们通过命令:python manage.py makemigrations
生成迁移文件,会看到以下显示:
Migrations for 'mybookapp':
0001_initial.py:
- Create model BookInfo
并且在mybookapp目录中会有一个migrations
文件夹出现,里面就是迁移文件0001_initial.py
接下来我们命令:python manage.py migrate
来对数据进行迁移,在数据库中创建模型所对应的表,会出现如下显示:
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: mybookapp, auth, contenttypes, admin, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying mybookapp.0001_initial... OK
Applying sessions.0001_initial... OK
这代表已经迁移完成了。
此时在django项目根目录会看到db.sqlite3
文件,默认情况下,django时使用sqllite作为数据库配置的,因为它轻量。
当然,官方也提到:如果你希望使用另外一种数据库,请配置合适的database binding,并在 DATABASES 'default’条目中修改以下的配置以匹配你的数据库连接的设置。
我们此时使用Navicat或者其他的数据可视化工具可以看到对应的数据库和表:
其中表的命名格式为:应用名称+模型类名称小写
,在表字段中,我们不需要在模型类中设置id,因为会自动生成
那么此时我们的项目结构如下:
有了表之后我们就可以向表中的字段添加数据了,我们可以在django项目命令行中进行操作,我执行python manage.py shell
进入命令行终端:
这实际上就是一个基于pythonIDLE的命令行,我们要在上面做如下操作:
- 导入模型
- 创建模型对象
- 修改对象属性
输入如下:
>>> from mybookapp.models import BookInfo
>>> bki = BookInfo()
>>> bki.bookName = "黑客"
>>>> from datetime import time
>>> bki.bookDate = time(14,30)
>>> bki.save()
回到表中查看:
根据上述方法,我们再定义一个人物类模型:
生成迁移文件,返回:
Migrations for 'mybookapp':
0002_peopleinfo.py:
- Create model PeopleInfo
我们来看一下迁移文件的内容(把两个迁移文件都打开):
-
dependencies的类型是一个列表,里面存储的是一个数组,数组里存放的数据就是需要依靠的迁移文件,也就是上一次的迁移文件。
-
operations的类型也是一个列表,列表里存储了创建模型对象,该对象有两个参数,一个表名称,一个字段数据【以列表加元组的的形式存储】
执行迁移,返回:
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: contenttypes, auth, sessions, mybookapp, admin
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying mybookapp.0002_peopleinfo... OK
由于第一个文件已经迁移,第二个文件没有迁移,所以对第二个文件进行迁移,在数据库中可以看到该表:
向表中添加第一条数据:
>>> from mybookapp.models import BookInfo,PeopleInfo
>>> ppi = PeopleInfo()
>>> ppi.peopleName = "石磊"
>>> ppi.peopleAge = "20"
>>> ppi.peopleComment = "少年天才黑客,金三角之王"
>>> bki = BookInfo.objects.get(id=1)
>>> ppi.peopleKey = bki
>>> ppi.save()
向表中添加第二条数据:
>>> ppi_2 = PeopleInfo()
>>> ppi_2.peopleName = "小李子"
>>> ppi_2.peopleAge = "20"
>>> ppi_2.peopleComment = "物理天才,机械之王"
>>> ppi_2.peopleKey = bki
>>> ppi_2.save()
>>># delete()方法可以删除该字段
查看数据库:
查看对象信息:
>>> bki.peopleinfo_set.all()
[<PeopleInfo: PeopleInfo object>, <PeopleInfo: PeopleInfo object>]
>>> BookInfo.objects.all()
[<BookInfo: BookInfo object>]
>>> PeopleInfo.objects.all()
[<PeopleInfo: PeopleInfo object>, <PeopleInfo: PeopleInfo object>]
(五)Django后台管理
通过python manage.py createsuperuser
来创建一个超级用户:
通过python manage.py runserver
来开启django服务器:
接着进入到admin目录,使用刚才创建的超级用户登录:
我们发现,页面貌似是英文的,这时我们可以通过settings.py
文件通过配置LANGUAGE_CODE
来设置,同时还可以更改TIME_ZONE
来设置时区:
LANGUAGE_CODE = 'zh-hans' #中文
TIME_ZONE = 'Asia/Shanghai' #中国时间
再次回到页面可以发现变成了中文:
接下来我们再admin.py
中去注册我们的模型类,在该页面展示的模型管理,添加代码:
from django.contrib import admin
import mybookapp.models
admin.site.register(mybookapp.models.BookInfo)
admin.site.register(mybookapp.models.PeopleInfo)
在页面中有显示两个表的管理:
进入people info的管理页面,会发现两条数据以PeopleInfo object
为名字显示:
原因就是页面所显示的名称是将当前的对象转化为一个字符串进行显示:
那么这个时候我们就可以通过重写__str__
方法,使其返回值为人物的名称,这样当再次将对象转化为字符串进行显示时就是人物的名称了:
当前好像只显示了一个字段,我们再通过admin.py文件进行自定义模型管理页面类:
(六)视图
视图(view)是Django应用中的一“类”网页,它通常使用一个特定的函数提供服务,并且具有一个特定的模板。
在Django中,网页的页面和其他内容都是由视图来传递的(视图对WEB请求进行回应)。每个视图都是由一个简单的Python函数(或者是基于类的视图的方法)表示的。Django通过检查请求的URL(准确地说,是URL里域名之后的那部分)来选择使用哪个视图。
Django使用叫做‘URLconfs’的配置来为URL匹配视图。 一个URLconf负责使用正则表达式将URL模式匹配到视图。
来到mybookapp应用目录下,通过views.py
创建视图函数,视图函数需要接收接收一个请求:
from django.http import HttpResponse
def index(request):
return HttpResponse('hello word')
这个是是Django中最简单的视图。 为了能够调用这个视图,我们需要将这个视图映射到URL上–>利用一个URLconf。
在mybookapp下我们需要创建一个urls.py
,可以自定义URLconf名称,在urls.py中我们写入代码:
from django.conf.urls import url
from mybookapp import views
urlpatterns = [
url(f'^index/$',views.index)
]
下一步,让主URLconf可以链接到mybookapp.urls模块。在mybookproject/urls.py中插入一个include():
url(r'^',include("mybookapp.urls")), #将除了admin/之外的访问内容都传给应用程序的urls匹配数据,随后通过对应的视图函数展现
现在我们已经将一个index视图关联到URLconf中。
我们编写更多的视图,只需按照上述步骤创建视图函数,随后将这个视图映射到URL上即可:
在浏览器中输入地址后面更上/index2
,即可看到“你好世界”:
我们先来说一下这里的工作原理:
- 首先打开浏览器,输入
127.0.0.1:8000/index
后 - index传到主URLconf中,在主URLconf中,先从第一个正则匹配,直到有匹配成功的,就会将index传入include导入的包内模块
- 应用mybookapp中的URLconf就会按照同样道理将index一次进行正则匹配,直到有匹配成功,则会调用相应的视图函数显示页面
- 由于主URLconf中正则匹配的任何开头内容,所以我们定义了视图函数之后,只需在mybookapp中进行正则匹配。
(七)模板
在Django中,模板(Templates)是用于呈现动态内容的HTML文件。模板引擎负责将视图中的变量和逻辑与模板中的占位符和标记结合起来,生成最终的HTML输出。为了使用Django的模板系统,我们需要配置模板引擎并创建模板文件。
在settings.py
文件中来配置模板引擎:
-
DIRS:这是一个列表,指定了模板文件存放的目录路径。可以添加多个目录。
-
APP_DIRS:如果设置为True,Django会在每个应用的templates子目录中查找模板。
-
context_processors:这是一个列表,包含了用于处理模板上下文的函数。这些函数会在模板渲染之前被调用,并将结果添加到模板的上下文中。
这里我们只需指定DIRS来设置模板文件存放路径即可。
在settings.py最开头我们注意到有一段代码:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
这段代码可以用来表示django项目的根目录,BASE_DIR是一个Python字符串,它包含了项目的绝对路径。这个变量在配置Django项目时非常有用,因为它允许你相对于项目根目录来引用其他文件或目录的路径。
这里我们的模板文件夹是templates
,里面的图书模板文件夹为booktest
通过views.py来加载渲染模板
index.html
文件如下:
最后我们通过浏览器查看index2
:
将加载文件、定义模板上下文、模板渲染写在一个方法可以方便后续的视图函数使用:
def my_render(request,template_path,context_dict={}):
temp = loader.get_template(template_path)
context = RequestContext(request,context_dict)
temp_text = temp.render(context)
return HttpResponse(temp_text)
def index2(request):
return my_render(request,'booktest/index.html')
当然这个函数在django中也有定义,不需要我们写,也就是一开始django就导入的render:
return render(request,'booktest/index.html',{})
接下来做一个传参的操作,在字典里指定键和值:
{'content':"welcome to django project !"}
在html页面中使用模板变量显示内容:{{content}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>booktest</title>
</head>
<body>
<h1>你好世界</h1><hr>
<p>{{content}}</p>
</body>
</html>
打开页面:
下面再实现一个for循环,在页面内显示0到9的数字
定义变量:
{'content':"welcome to django project !",'for_range':range(0,10)}
html页面内使用for循环:
<ul>
{% for i in for_range %}
<li>{{i}}</li>
{% endfor %}
</ul>
打开页面:
(八)书籍信息查看页面
在这个案例中,我们先需要创建两个模板文件,一个是显示书籍列表的模板,另一个是显示书籍人物信息的页面模板。
模板的路径我们在模板引擎中已经配置
此外我们会在视图中创建两个视图函数,与模板对应
在主URLconf中我们不需要进行配置,按照我们之前的配置进行即可
在应用的URLconf中,我们需要配置两个url的映射
这里的编辑代码就是:views.py、urls.py、show_book.html、show_people.html:
在urls.py中我们会对bookinfo/
、peopleinfo/(\d+)
进行严格的开头正则匹配。匹配成功之后执行的视图函数是views.show_book
、‘’
url(f'bookinfo/$',views.show_book)
url(f'peopleinfo/(\d+)$',views.show_people) #()分组之后,会自动将分组信息作为参数传递给视图函数
在视图函数中,我们编写对应的视图函数:
def show_book(request):
book_info = BookInfo.objects.all()
return render(request,'booktest/show_book.html',{'book':book_info})
def show_people(request,pid):
book_info_pid = BookInfo.objects.get(id=pid) #与id为点击书的id有关联的表对象
people_info = book_info_pid.peopleinfo_set.all() #获得这个表关联的数据对象
return render(request,'booktest/show_people.html',{'people':people_info})
在show_book.html中我们指定书名用一个a标签包裹,指向的href为/peopleinfo/{{book_name.id}}
,这样就会跳转到peopleinfo/{书的i}d中
此时我们就可以写peopleinfo/id的模板了:
python manage.py runserver 127.0.0.1:5555
开启服务,打开输入127.0.0.1:5555/bookinfo/:
点击黑客
会跳转到人物信息页面: