Django is an open source Web application framework written by Python. The framework model of MTV, namely model M, view V and template T, is adopted. It was originally developed to manage some news content oriented websites of the publishing group, that is, CMS (content management system) software. It was issued under BSD license in July 2005.
Install
- Install python
截止目前 python 的最新版本为python3.7.4
,django 需要的 python 版本如下
Django版本 | Python版本 |
---|---|
1.11 | 2.7,3.4,3.5,3.6,3.7 |
2.0 | 3.4,3.5,3.6,3.7 |
2.1, 2.2 | 3.5,3.6,3.7 |
python 安装方法比较简单,安装之后记得配置环境变量,这里就不做介绍了。
安装
virtualenv
Install django
创建并激活一个虚拟环境然后执行下面的命令或直接在系统中执行下面的命令pip3 install Django
然后在 python3 环境中执行下面代码,如果输出 django 版本,说明 django 安装成功1
2import django
print(django.get_version())
Create Project
运行下面命令创建项目django-admin startproject PROJECT_NAME
创建之后的目录与作用如下1
2
3
4
5
6
7PROJECT_NAME/ # 根目录,项目的容器
manage.py # 管理 django 项目的命令行工具
PROJECT_NAME/ # 项目目录。它是一个纯 python 包,名字是引用内部东西时需要用的 python 包名,如(PROJECT_NAME.urls)
__init__.py # 空文件。告诉 python 这个目录是一个 python 包
settings.py # django 项目的配置文件
urls.py # django 项目的 URL 声明,像网站的“目录”
wsgi.py # 作为项目运行在 wsgi 兼容的 web 服务器的入口
用于开发的简易服务器使用以下命令开启python3 manage.py runserver
runserver
命令会将服务器设置为监听本机内部 ip 的 8000 端口,想更换端口的话使用下面的命令python3 manage.py runserver PORT
Create APP
- 运行以下命令创建应用
python3 manage.py startapp APP_NAME
创建之后的目录如下1
2
3
4
5
6
7
8
9
10
11APP_NAME/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
# 这个文件是后期创建的,这个是 URL 映射的文件,创建完之后需要在 PROJECT_NAME/urls.py 中加入 include()
urls.py
views.py - 将应用安装到项目里
在PROJECT_NAME/settings.py
中的INSTALLED_APPS
中添加APP_NAME.apps.APP_NAMEConfig
—-APP_NAMEConfig
的APP_NAME
首字母大写。因为APP_NAMEConfig
类写在文件APP_NAME/apps.py
中,所以它的点式路径是APP_NAME.apps.APP_NAMEConfig
View
添加视图,修改文件 PROJECT_NAME/APP_NAME/views.py
如下1
2
3
4
5
6
7
8
9
10from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. This is an APP.")
def VIEW_NAME(request,PARAMETER):
response = "This is a simple view"
return HttpResponse(response % PARAMETER)
...
设置路由,修改文件 PROJECT_NAME/urls.py
如下1
2
3
4
5
6
7
8
9
10from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('ROUTER_NAME', views.VIEW_NAME, name='VIEW_NAME')
# 使用尖括号捕获URL 并且以参数的形式发送给视图函数
path('<ROUTER_NAME:PARAMETER>', views.VIEW_NAME, name='VIEW_NAME')
...
]
修改 PROJECT_NAME/urls.py
的内容如下1
2
3
4
5
6
7
8from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('APP_NAME/', include('APP_NAME.urls')),
...
]
path()
函数总共有四个参数,分别是route
、view
、kwargs
、name
,前两个是必须参数,后两个是可选参数,参数意义如下
route
这是一个匹配 URL 的准则,当 django 响应一个请求时,会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项view
当 django 找到一个匹配的准则,会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入kwargs
任意个关键字参数可以作为一个字典传递给目标视图函数name
为你的 URL 取名能使你在 django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式
Django模版系统
如果页面的设计写死在视图函数的代码里的,则修改页面的样子需要编辑 Python 代码,如果使用 Django 的模板系统,只要创建一个视图,就可以将页面的设计从代码中分离出来。具体使用方法如下
- 在 PROJECT_NAME 目录里创建一个
templates
目录,django 将会在这个目录里查找模版文件
项目的
TEMPLATES
配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了DjangoTemplates
后端,并将APP_DIRS
设置成了True
。这一选项将会让DjangoTemplates
在每个INSTALLED_APPS
文件夹中寻找 “templates” 子目录。所以如果templates
文件夹在APP_NAME
目录中,就算没有修改DIRS
设置,Django 也能正确找到 APP_NAME 的模板位置,但是如果目录在其它地方,就必须设置DIRS
TEMPLATES
配置如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
在
templates
目录里创建一个APP_NAME
目录,此时模版文件的路径就是APP_NAME/templates/APP_NAME/VIEW_NAME.html
,使用APP_NAME/VIEW_NAME.html
就可以引用相应的模版了APP_NAME/views.py
文件的设置如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
from django.template import loader
from app1.models import User
from app1.models import Job
def index(request):
latest_user_list = User.objects.order_by('name')[:3]
template = loader.get_template('app1/index.html')
context = {
'latest_user_list' : latest_user_list,
}
return HttpResponse(template.render(context,request))render()
函数render()
作用是载入模版,填充上下文,再返回由它生成的HttpResponse
对象,使用此函数重写index()
视图如下1
2
3
4
5
6
7
8
9
10
11
12from django.shortcuts import render
from django.http import HttpResponse
from app1.models import User
from app1.models import Job
def index(request):
latest_user_list = User.objects.order_by('name')[:3]
context = {
'latest_user_list' : latest_user_list,
}
return render(request, 'app1/index.html', context)抛出404
如果查询指定的内容不存在,则抛出一个Http404
异常1
2
3
4
5
6
7
8
9
10
11
12from django.shortcuts import render
from django.http import HttpResponse, Http404
from app1.models import User
from app1.models import Job
def index(request, user_name):
try:
user_detail = User.objects.get(name=user_name)
except User.DoesNotExist:
raise Http404("User does not exist !")
return render(request, 'app1/index.html', {'user': user_detail})get_object_or_404()
实现方法如下1
2
3
4
5
6
7
8from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404
from app1.models import User
from app1.models import Job
def index(request, user_name):
user_detail = get_object_or_404(User, name=user_name)
return render(request, 'app1/index.html', {'user': user_detail})
第三方模版系统
Model
设置时区
TIME_ZONE
默认为UTC
是国际标准时间“格林尼治时间”,中国的时间有Asia/Shanghai
、Asia/Chongqing
USE_TZ
用于控制是否使用 UTC 时间(true and false),如果设置为 false,则使用本地时间LANGUAGE_CODE
默认为en-us
,设置中文为zh-Hans
编辑
PROJECT_NAME/settings.py
PROJECT_NAME/settings.py
包含了 django 项目设置的 python 模块,配置文件使用 SQLite 作为默认数据库,使用其他数据库则需要安装相应的 python 数据库绑定,具体如下PostgreSQL
需要安装psycopg2
包MySQL
需要安装DB API driver
,如mysqlclient
mysqlclient
安装方法如下pip3 install mysqlclient
Oracle
需要cx_Oracle
的副本安装完之后需要改变设置中
DATABASES 'default'
项目中的一些键值ENGINE
可选值有django.db.backends.sqlites
,django.db.backends.postgresql
,django.db.backends.mysql
或django.db.backends.oracle
NAME
数据库的名称。如果使用 SQLite,数据库将是电脑上的一个文件,此时NAME
是此文件的绝对路径,包括文件名- 如果使用的不是 SQLite ,则必须添加一些额外设置,比如
USER
、PASSWORD
、HOST
,设置如下1
2
3
4
5
6
7
8
9
10DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
若要使用 django 的
manage.py
migrate
命令为您的模型自动创建数据库表,则需要确保 django 有权在您正在使用的数据库中创建和更改表
如果你打算手动创建这些表,你可以只需授予 Djangoselect
、insert
、update
和delete
权限
INSTALLED_APPS
设置包括了项目中启用的所有 django 应用,默认为1
2
3
4
5
6django.contrib.admin # 管理员站点
django.contrib.auth # 认证授权系统
django.contrib.contenttypes # 内容类型框架
django.contrib.sessions # 会话框架
django.contrib.messages # 消息框架
django.contrib.staticfiles # 管理静态文件的框架这些应用被默认启用是为了给常规项目提供方便,默认开启的某些应用需要至少一个数据表,故在使用他们之前需要在数据库中创建一些表,命令如下
python3 manage.py migrate
migrate
命令检查INSTALLED_APPS
设置,为其中的每个应用创建需要的数据表创建模型
编辑APP_NAME/models.py
,如下1
2
3
4
5from django.db import models
class MODEL_NAME(models.Model):
FIELD_NAME = models.TYPE(max_length=MAX_LENGTH | default = DEFAULT_VALUE)
...TYPE
中字符字段被表示为CharField
,日期时间字段被表示为DateTimeField
,ForeignKey
定义一个关系,将相应的对象关联到另一个对象,详细的字段类型见下表
名称 | 类型 | 大小 | 备注 |
---|---|---|---|
AutoField |
int auto increment |
int |
一般不用,主键一般会自动创建 |
IntegerField |
int auto increment |
64-bit |
一般不用,主键一般会自动创建 |
BigIntegerField |
long int |
64-bit |
|
BinaryField |
binary |
max_length |
|
BooleanField |
bool |
||
CharField |
char |
max_length |
|
DateField |
date |
auto_now | auto_now_add |
|
DateTimeField |
date&time | auto_now | auto_now_add |
|
DecimalField |
固定精度的十进制 | max_digits | decimal_places |
|
DurationField |
一段时间的字段类型 | ||
EmailField |
email |
max_length |
|
FileField |
文件上传类型 | upload_to | max_length |
|
FilePathField |
文件目录类型 | path | match | recursive | max_length |
|
ImageField |
图片类型 | upload_to | height_field | width_field | max_length |
|
IntegerField |
int |
-2147483648 - 2147483647 |
|
PositiveIntegerField |
int |
0 - 2147483647 |
|
PositiveSmallIntegerField |
int |
0 - 32767 |
|
SmallIntegerField |
int |
-32768 - 32767 |
|
TextField |
char |
max_length |
|
TimeField |
time |
auto_now | auto_now_add |
|
URLField |
URL |
max_length |
|
ForeignKey |
关联关系字段 | to | on_delete |
激活模型
python3 manage.py makemigrations APP_NAME
运行makemigrations
命令,django 会检测你对模型文件的修改,并且把修改的部分存储为一次迁移,迁移是 django 对于模型定义(也就是你的数据库结构)的变化的储存形式,其实也只是一些你磁盘上的文件,它被储存在APP_NAME/migrations/0001_initial.py
里。
使用sqlmigrate
可以查看模型的迁移信息,它可以接收一个迁移的名称,用法如下python3 manage.py sqlmigrate APP_NAME 0001
其中0001
是一个迁移的名称
之后如果定义了新模型的话,可以直接运行下面的命令创建python3 manage.py migrate
migrate
命令选中所有还没有执行过的迁移(django 通过在数据库中创建一个特殊的表 django_migrations 来跟踪执行过哪些迁移)并应用在数据库上(也就是将你对模型的更改同步到数据库结构上)。改变模型
- 编辑
models.py
文件,改变模型 - 运行
python3 manage.py makemigrations
为模型的改变生成迁移文件 - 运行
python3 manage.py migrate
来应用数据库迁移
- 编辑
Django API
使用下面命令进入交互式 Python 命令行python3 manage.py shell
这个命令中 manage.py
会设置 DJANGO_SETTINGS_MODULE
环境变量,这个变量会让 django 根据 PROJECT_NAME/settings.py
文件来设置 python 包的导入路径
Database
数据库操作是项目必不可少的,以下介绍 django 的数据库操作的 API
- Insert
save()
、create()
1
2
3
4
5
6
7# 插入
tmp = MODEL_NAME(FIELD_NAME=‘FIELD_VALUE’,...)
tmp.save()
# 修改
MODEL_NAME.FIELD_NAME = 'FIELD_VALUE'
MODEL_NAME.save()1
MODEL_NAME.objects.create(FIELD_NAME="FIELD_VALUE",...)
- Select
objects
从数据库检索对象要通过模型类的manager
构建一个querySet
。querySet
代表来自数据库中对象的一个集合。它可以有 0 个,1 个或者多个filters
.filters
可以根据给定参数缩小查询结果量。在 SQL 的层面上,queryset
对应select
语句,而过滤器对应类似where
或limit
的限制子句。可以通过模型的manager
获取querySet
。每个模型至少有一个manager
,默认名称是objects
。用法如下过滤器1
2# 检索全部对象,返回值是一个 queryset,包含所有的 MODEL_NAME 对象
ALL_MODEL = MODEL_NAME.objects.all()
- all() —> 查询所有
- filter( **kwargs ) —> 使用过滤器查询
- exclude( **kwargs ) —> 条件查询
- get( **kwargs ) —> 查询
**kwargs
为参数,参数的形式为FIELD_NAME__LOOKUPTYPE=VALUE
(有个双下划线)
其中__LOOKUPTYPE
具体有
参数 | 作用 |
---|---|
__exact |
精确等于 |
__iexact |
精确等于,忽略大小写 |
__contains |
包含 |
__icontains |
包含,忽略大小写 |
__gt |
大于 |
__gte |
大于等于 |
__lt |
小于 |
__lte |
小于等于 |
__in |
存在于一个list范围内 |
__startswith |
以…开头 |
__istartswith |
以…开头,忽略大小写 |
__endswith |
以…结尾 |
__iendswith |
以…结尾,忽略大小写 |
__range |
在…范围内 |
__year |
日期字段的年份 |
__month |
日期字段的月份 |
__day |
日期字段的日 |
__isnull |
True/False |
在查询的过程中 pk
表示主键,如1
2# 查询主键为 1 的数据
MODEL_NAME.objects.get(pk=1)
跨关系查询
Delete
delete()
删除方法被命名为 delete()。该方法立刻删除对象,并返回被删除的对象数量和一个包含了每个被删除对象类型的数量的字典,也能批量删除对象。所有 QuerySet 都有个 delete() 方法,它会删除 QuerySet 中的所有成员update()
1
MODEL_NAME.objects.filter().update(FIELD_NAME='NEW_FIELD_VALUE')
原生SQL查询
Django 允许你用两种方式执行原生 SQL 查询:你可以使用 manager.raw()
来执行原生查询并返回模型实例,或者完全不用模型层 直接执行自定义 SQLmanager.raw(raw_query,params=none,translations=none)
1
MODEL_NAME.objects.raw('SQL statement')
除了上面的 manager.raw()
之外,如果想要功能更强大的查询,可以使用下面的方法绕过模型层,直接访问数据库
对象 django.db.connection
代表默认数据库连接。要使用这个数据库连接,调用 connection.cursor()
来获取一个指针对象。然后,调用 cursor.execute(sql,[params])
来执行该 SQL 和 cursor.fetchone()
或 cursor.fetchaall()
获取结果数据,使用方法如下1
2
3
4
5
6
7
8
9from django.db import connection
def custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("SQL insert statement", [self.baz])
cursor.execute("SQL select statement", [self.baz])
row = cursor.fetchone()
return row
要避免 SQL 注入,你绝对不能在 SQL 字符串中用引号包裹
%s
占位符,若要在查询中包含文本的百分号,你需要在传入参数使用两个百分号
Django 管理页面
- 创建管理账号
python3 manage.py createsuperuser
启动开发服务器之后通过http://127.0.0.1:8000/admin/
就可以看到管理员登录界面 - 添加被管理的应用
如果想要一个应用被管理,只需要将应用加入APP_NAME/admin.py
文件即可,具体如下1
2
3
4
5from django.contrib import admin
from .models import MODEL_NAME
admin.site.register(MODEL_NAME)
...
配置Django运行环境
如果要在生产站点上使用 django ,则需要搭建 Apache 或者 Nginx 服务器,具体搭建方法如下
Apache&mod_wsgi
- Install Apache
Nginx&uWSGI
- Install Nginx

...
...
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !