创建Django项目
打开cmd
命令行,进入到存放Django
项目的文件夹,例如我这里进入这个路径:D:\学习笔记\Web开发\test
输入以下代码
1 | django-admin startproject django_demo |
输入完成后可以看到在当前文件夹下面生成了一个django_demo
文件夹,这个文件夹即为我们创建的Django
工程。
使用Pycharm
打开工程,可以看到Django
项目的目录结构如下。
相关文件的作用如下:
文件 | 说明 |
---|---|
manage.py |
Django 程序执行的入口 |
asgi.py |
一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。 |
settings.py |
Django 总的配置文件,可以配置APP 、数据库、中间件、模板等诸多选项 |
urls.py |
Django 默认的路由配置文件,可以在其中使用include包含其他路径下的urls.py |
wsgi.py |
Django 实现的WSGI 接口的文件,用来处理Web请求 |
运行项目
1 | python manage.py runserver |
可以看到服务器已经开始监听8000端口了。
在浏览器中输入127.0.0.1:8000
即可访问Django
项目。
并且,项目自动给我们生成了一个db.sqlite3
数据库文件,Django
默认使用这种小型数据库存取数据。也可以根据自己的实际情况在settings.py
中进行修改为其他数据库,例如:Mysql
等。
使用命令创建后台应用
按Ctrl+C
组合键关闭服务器,然后执行如下命令执行数据库迁移,生成数据表
1 | python manage.py migrate |
创建超级管理员用户
1 | python manage.py createsuperuser |
输入相关帐号、邮箱、密码完成注册。
再次启动服务,进入127.0.0.1/admin
,即可进入后台登录界面
登录界面
输入帐号密码,完成登录,进入后台管理界面。
创建一个APP
在Django
项目中,推荐使用App
来完成不同模块的任务,启用一个App非常简单,执行以下命令。
1 | python manage.py startapp app1 |
运行完毕后,django_demo
目录下又多了一个app1
的目录。
打开app1
目录,其文件结构如下:
文件 | 说明 |
---|---|
migrations |
执行数据库迁移生成的脚本 |
admin.py |
配置Django 管理后台的文件 |
apps.py |
单独配置添加的每个App 的文件 |
models.py |
创建数据库数据模型对象的文件 |
tests.py |
用来编写测试脚本的文件 |
views.py |
用来编写视图控制器的文件 |
仅仅创建App
还不能直接使用,还需要对其进行激活。激活的方式非常简单,在django_demo/settings.py
配置文件中,找到INSTALLED_APPS
列表,添加app1
。
数据模型
在App
中添加数据模型(models
)
1 | from django.db import models |
Person
模型中每一个属性都指明了models
下面的一个数据类型,代表了数据库中的一个字段。
上面的类在数据库中会创建如下的表。
1 | CREATE TABLE myapp_person( |
对于一些公有的字段,为了优雅的简化代码,可以使用如下的实现方式:
1 | from django.db import models |
这时候需要创建日期和修改日期的数据模型都可以继承于CreateUpdate
类。
在上面创建表时使用了2个字段类型:CharField
和DateTimeField
,它们分别为字符串值类型和日期时间类型。此外,django.db.models
还提供了很多常见的字段类型,如下表所示。
字段类型 | 说明 |
---|---|
AutoField |
一个id自增的字段,但在创建表过程中,Django 会自动添加一个自增的主键字段 |
BinaryField |
一个保存二进制源数据的字段 |
BooleanField |
一个布尔值字段,应该指明默认值,在管理后台中默认呈现为CheckBox 形式 |
NullBooleanField |
可以为None的布尔值字段 |
CharField |
字符串值字段,必须指明参数max_length 值,在管理后台中默认呈现为TextInput 形式 |
TextField |
文本域字段,对于大量文本应该使用TextField 。在管理后台中默认呈现为Textarea 形式 |
DateField |
日期字段,代表Python 中datetime.date 的实例。在管理后台中默认呈现为TextInput 形式 |
DateTimeField |
日期时间字段,代表Python 中的datetime.datetime 实例。在管理后台中默认呈现TextInput 形式。 |
EmailField |
邮件字段,是CharField 的实现,用于检查该字段值是否符合邮件地址格式。 |
FileField |
上传文件字段,在管理后台中默认呈现为ClearableFileInput 形式 |
ImageField |
图片上传字段,是FileField 的实现。在管理后台中默认呈现为ClearableFileInput 形式 |
IntegerField |
整数值字段,在管理后台中默认呈现为NumberInput 或者TextInput 形式 |
FloatField |
浮点数值字段,在管理后台中默认呈现为NumberInput 或者TextInput 形式 |
SlugField |
只保存字母、数字、下划线和连接符,用于生成URL 的短标签 |
UUIDField |
保存一般统一标识符的字段,代表Python 中UUID 的实例,建议提供默认值default |
ForeignKey |
外键关系字段,需提供外键的模型参数和on_delete 参数(指定当该模型实例删除时,是否删除关联模型),如果要外键的模型出现在当前模型后面,需要在第一个参数中使用单引号'Manufacture' |
ManyToManyField |
多对多关系字段,与ForeignKey 类似 |
OneToOneField |
一对一关系字段,常用于扩展其他模型 |
执行数据库迁移
完成数据模型后,开始做数据库迁移。如果不使用Django
默认自带的sqlite
数据库,而是使用当下比较强大的MySQL
数据库,那么,需要在django_demo/setting.py
配置文件中进行如下修改。
原始内容:
1 | DATABASES = { |
修改为(注:要使用MySQL
数据库首先需要自己在本地进行数据库的安装,并创建好数据库django_db
):
1 | DATABASES = { |
然后在django_demo/__init__.py
文件中,添加以下代码
1 | import pymysql |
然后在控制台中执行以下代码,将数据库迁移至MySQL
。
1 | python manage.py makemigrations # 生成迁移文件 |
生成迁移文件
在
app1/migrations
下生成了一个迁移文件,如下图所示迁移数据库,创建新表
打开数据库可视化软件Navicat
可以看到数据库中生成很多表格
Django
会默认按照App名称+下划线+模型类名称小写
的形式创建数据表。
如上图中的:
app1_order
app1_person
在这里有人可能就有疑问了,我们在models
数据模型中定义了三个数据类,为什么这里只生成了两个,CreateUpdate
为什么没有生成表格?
是因为我们在数据类定义过程中,在CreateUpdate
中加上了以下代码,将其设置为抽象类,该表不会在数据库中进行创建。
1 | class Meta: |
了解Django
数据API
启用交互式命令行
在cmd
控制台中输入:python manage.py shell
启动交互式命令行。
接下来就在交互式命令行中输入相关代码对数据库中的数据进行操作。
要操作数据库,首先需要将数据模型导入进来
1 | from app1.models import Person, Order |
接下来使用相关命令对数据库中的表格进行增删改查。
创建数据
首先使用数据模型创建一个数据实例,然后调用实例对象的save()方法进行数据的存储。
1 | # 在Person表格中插入first_name='luo', last_name='ming' |
打开表格可以看到,当前数据已经被插入到数据库中
此外还可以只插入一个字段名称,例如:只设置first_name='L'
1 | p = Person(first_name='L') |
查询数据
查询所有数据
调用Person.onjects.all()
方法
1 | Person.objects.all() |
查询单个数据
调用Person.objects.get()
方法,注意该方法必须返回一个确定的值,当条件匹配到了多条值的时候就会报错。
1 | Person.objects.get(id=1) |
查询指定条件的数据
调用Person.objects.filter()
方法
- 查找指定
first_name
字段值,例如:luo
1 | Person.objects.filter(first_name__exact='luo') |
- 查找
id
值大于1的数据
1 | Person.objects.filter(id__gt=1) |
条件符号汇总:
符号 | 意义 |
---|---|
__exact |
精确等于 |
__iexact |
精确等于(忽略大小写) |
__contains |
包含 |
__icontains |
包含(忽略大小写) |
__gt |
大于 |
__gte |
大于等于 |
__lt |
小于 |
__lte |
小于等于 |
__in |
存在于一个list范围内 |
__startswith |
以…开头 |
__istartswith |
以…开头(忽略大小写) |
__endswith |
以…结尾 |
__iendswith |
以…结尾(忽略大小写) |
__range |
在…范围内 |
__year |
日期字段的年份 |
__month |
日期字段的月份 |
__day |
日期字段的日 |
__isnull |
是否为空 |
查看具体的数据内容
前面我们查询到的所有数据,都是QuerySet
格式,无法看到具体内容,我们可以调用其values()
方法,查看具体数据。
1 | Person.objects.filter(id__gt=1).values() |
当不传入任何参数到values()
中时,返回所有的字段数据。
当我们只想输出指定字段时,可以在values()
方法中进行指定。例如:只要查询出来的first_name
和last_name
字段。
1 | Person.objects.filter(id__gt=1).values(first_name, last_name) |
修改数据
修改之前需要先查询到对应的数据,再使用类似于属性修改的方式进行赋值,最后同样调用save()
属性进行提交。
- 将
first_name=L
的数据last_name
改为M
1 | p = Person.objects.get(first_name='L') |
删除数据
删除数据同样需要先查找到对应的数据,然后调用delete()
方法进行删除,代码如下:
1 | Person.objects.get(first_name='luo').delete() |
打开数据库发现该条记录已被删除
管理后台
定义好数据模型,就可以配置管理后台了,按照如下代码编辑app1
的admin.py
文件。
1 | from django.contrib import admin # 导入admin模块 |
配置完成后,进入http://127.0.0.1:8000/admin
单击App1
$\rightarrow$ Person
效果如下图所示
路由
Django
路由(urls
)系统的作用就是使views
中处理数据的函数与请求的URL建立映射关系。使请求到来之后,根据urls.py
中的关系条目,查找到与请求对应的处理方法,从而返回给客户端HTTP
页面数据。
在app1
目录下创建urls.py
文件,并定义路由规则,代码如下:
1 | from django.urls import path, re_path |
定义每个路由的视图规则,在app1
目录下的views.py
文件中编写视图函数
1 | from django.http import HttpResponse |
将app1
中的路由加入到总路由【django_demo中的urls.py文件】
中,只有加入后才能够通过URL地址进行访问。如果没有加到总路由中,会出现404
错误。
1 | from django.contrib import admin |
- 访问:
http://127.0.0.1:8000/app1/
- 访问:
http://127.0.0.1:8000/app1/article/12
- 访问:
http://127.0.0.1:8000/app1/articles/22/10/lm/
- 访问:
http://127.0.0.1:8000/app1/articles/2022/
表单
在app1
文件夹下创建一个表单(forms
)文件forms.py
,添加如下类代码。
1 | from django import forms |
PersonForm
类将呈现为下面的HTML代码。
1 | <label for='你的名字'>你的名字:</label> |
forms.Form
表单类有一个is_valid()
方法,可以在views.py
中验证提交的表单是否符合规则。
对于提交的内容,在views.py
增加如下代码
1 | def get_name(request): |
注意:这里的视图函数与前面稍微有点不同,前面是直接返回HTTP响应,响应的文字内容是自己在函数中定义的。这里返回的是remder()
函数对应的结果,这个函数会调用本地的静态HTML文件做为网页的显示内容。
例如:这里返回render(request, 'name.html', {'form': PersonForm()})
意思是,返回页面为name.html
文件,{'form': PersonForm()}
意思是传入到name.html
文件中的参数form值是通过表单类PersonForm()
获取的。
并且html
静态文件需要放入,app1
目录下的templates
文件夹中,这个文件夹初始是不存在的,需要自己手动创建。文件夹建立好后,创建HTML
文件,文件内容为:
1 |
|
其中{{form}}
,表示该参数需要通过后端获取。
此时工程文件目录如下:
视图函数和相关页面建立好后,还需要再urls
中进行路由关联。
在urlpatterns
列表中加入path('get_name', app1.views.get_name)
1 | from django.urls import path, re_path |
- 访问:
http://127.0.0.1:8000/app1/get_name
输入名字和姓氏,点击提交。得到如下返回结果。
视图
前面我们已经使用过了app1
的路由和视图,并将它们两者进行了关联。路由用来获取用户的访问请求,获取到请求后将响应对应到视图中,让视图函数进行进一步处理并返回页面内容。
此外,我们还可以给根目录定义相关的视图。
需要在与app1
同级的目录django_demo
下创建views.py
文件。
1 | from django.http import HttpResponse |
然后在总路由中进行关联。
1 | from django.contrib import admin |
关联后访问,根目录(http://127.0.0.1:8000/
)就会出现以下页面内容。