常用命令
- 创建项目:
django-admin startproject 项目名
- 创建子应用:
python manage.py startapp 子应用名
- 生成迁移文件:
python manage.py makemigrations
- 执行迁移:
python manage.py migrate
- 启动项目:
python manage.py runserver
- 创建自带的后台管理账户:
python manage.py createsuperuser
项目配置
settings配置
- 数据库:根据驱动程序不同,配置的参数不同,参考官方文档,下面是mysql-connector-python的配置
DATABASES = { 'default': { 'NAME': '数据库名', 'ENGINE': 'mysql.connector.django', 'HOST': '主机地址', 'PORT': 端口号, 'USER': '用户名', 'PASSWORD': '密码', 'OPTIONS': { 'autocommit': True, # 'use_pure': True, # 'init_command': "SET foo='bar';" }, } }
- 启用子应用:在
INSTALLED_APPS
常量中加上你需要启用的子应用的配置路径(子应用名.apps.配置类名
) - 语言:中文设置(
zh-Hans
) - 时区:北京时间(
Asia/Shanghai
) - 静态资源路径:直接访问静态资源时的路径地址,一般在项目根目录创建一个static文件夹,在settings文件中添加(
STATICFILES_DIRS = os.path.join(BASE_DIR, "static")
)
路由配置
- 在子应用中创建
urls.py
文件 - 在文件中创建
urlpatterns
列表 - 在主应用的
urls.py
文件下将子应用路由配置包含进来,写法:path('子应用路由入口',include('子应用名.urls'))
视图函数
- 视图函数接收的第一个参数是
HttpRequest
对象 - 视图函数返回值必须是
django.http.response
中的其中一个HttpResponse
类的对象
HttpRequest对象
http请求包含有请求行、请求头、请求体
- 通过http传参的方式:
- 请求行传参:在路由配置中,用
<参数名>
接收路径参数,Django会以关键字参数形式传递给视图函数,例如path('<username>/<password>/', login)
,这个路由配置会接收例如http://www.test.com/xiaoming/123456
中的xiaoming
和123456
两个参数,以关键字参数{"username":"xiaoming","password":"123456"}
传递给login函数 - 请求参数字符串:
paramas
在HttpRequest中调用.GET
获取到QueryDict
对象,类字典,支持一键多值 - 请求头:使用
.headers
获取请求的请求头参数,也是类字典对象 - 请求体:使用
.body
获取请求的请求体,获取类型为二进制
- 请求行传参:在路由配置中,用
- 转换器:在请求行参数传递时,可以预定义参数类型,默认提供的转换器有
int、path、slug、str、uuid
,在路由配置中写法为path('<str:username>/<str:password>/', login)
- 自定义转换器:定义一个类,类属性
regex
表示正则匹配的规则,实现to_python
和to_url
方法,然后注册就可以在项目中使用了,下面是一个例子
from django.urls.converters import register_converter
class EmailConvertor:
regex = r"[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com"
def to_python(self, value):
return value
def to_url(self, value):
return value
register_converter(EmailConvertor, "email")
使用自定义转换器:path('<email:varname>/', test)
HttpResponse对象
HttpResponse是所有响应的基类
主要关注点:
- headers:响应头
- content:响应体
- content_type:响应类型
- status:响应状态码
重定向
重定向的方法是
redirect
,在django.shortcuts
中
Cookie和Session
Cookie的设置和获取
- cookie设置:调用
HttpResponse
对象的set_cookie
方法 - cookie获取:调用
HttpRequest
对象的COOKIES
获取cookie字典
Session会话存储
- session的操作都是通过
HttpRequest
对象的session
进行,可以把它看做一个类字典对象 - 默认session都是存储在数据库中,可以修改
settings.py
添加缓存配置,然后配置SESSION_ENGIN
让session存储在缓存服务器中
类视图函数
- 类视图函数必须继承
django.views.View
- 实例方法命名以可接受请求访问方法的小写形式命名,比如
GET
请求需要在类中定义get(self, request)
方法,POST
请求需要在类中定义post(self, request)
方法,其他的以此类推 - 路由配置:
path('路由', 类名.as_view())
as_view()
方法返回值是视图函数的引用
示例:
views.py
class LoginView(View):
def get(self, request):
return HttpResponse("get请求")
def post(self, request):
return HttpResponse("post请求")
urls.py->urlpatterns
path("login/", LoginView.as_view())
数据模型
模型创建
- 继承
models.Model
- 会自动创建主键id,不需要手动定义id字段
- 类属性都是
models
下的字段类型类对象 - 表名修改需要在类的内部定义一个内部类Meta
class 类名(models.Model):
类属性名 = models.字段类型(参数) # 对应字段名
class Meta:
db_name = '自定义表名'
ORM操作
增加数据(insert)
- 创建类的实例化对象,调用save方法:
类名(
字段名1=字段值1,
字段名2=字段值2,
字段名3=字段值3,
...
).save()
- 使用父类的objects的create方法:
类名.objects.create(
字段名1=字段值1,
字段名2=字段值2,
字段名3=字段值3,
...
)
修改数据(update)
- 使用get获取数据对象,修改后调用save方法
obj = 类名.objects.get(id=1)
obj.字段名 = 新的字段值
obj.save()
- 使用filter直接过滤后调用update方法
类名.objects.filter(id=1).update(字段名=新的字段值)
删除数据(delete)
- 使用get获取数据对象,然后调用delete方法
类名.objects.get(id=1).delete()
- 使用filter过滤后调用delete()方法
类名.objects.filter(id=1).delete()
查询数据(select)
- 单条查询:
类名.objects.get(属性名__运算符=查询值)
- 多条查询:
类名.objects.filter(属性名__运算符=查询值)
- 取反查询:
类名.objects.exclude(属性名__运算符=查询值)
- 排除符合查询条件的结果
常用运算符:
运算符 | 描述 | 示例 |
---|---|---|
exact | 等于 | Model.objects.filter(field__exact=value) |
contains | 包含 | Model.objects.filter(field__contains=value) |
startswith | 开头 | Model.objects.filter(field__startswith=value) |
endswith | 结束 | Model.objects.filter(field__endswith=value) |
gt | 大于 | Model.objects.filter(field__gt=value) |
gte | 大于等于 | Model.objects.filter(field__gte=value) |
lt | 小于 | Model.objects.filter(field__lt=value) |
lte | 小于等于 | Model.objects.filter(field__lte=value) |
in | 在范围内 | Model.objects.filter(field__in=[value1, value2]) |
~Q() | 条件取反 | Model.objects.filter(~Q(field__exact=value)) |
F对象
from django.db.models import F
用于比较两个字段属性值:
类名.objects.filter(属性名__运算符=F('字段名'))
Q对象
from django.db.models import Q
用于进行条件逻辑运算,比如两个查询条件之间的与、或、非操作
- AND查询:
类名.objects.filter(Q(属性名__运算符=值) & Q(属性名__运算符=值))
- OR查询:
类名.objects.filter(Q(属性名__运算符=值) | Q(属性名__运算符=值))
- NOT查询:
类名.objects.filter(~Q(属性名__运算符=值))
聚合函数和排序
from django.db.models import Avg, Count, Sum, Max, Min
- 聚合查询:
类名.objects.aggregate(聚合函数('字段'))
- 正序排序:
类名.objects.filter(属性名__运算符=查询值).order_by('排序字段')
- 倒序排序:
类名.objects.filter(属性名__运算符=查询值).order_by('-排序字段')
外键关联查询(一对多)
- 查询主表关联的从表信息:
从表类.主表类名小写__set.all()
- 查询从表关联的主表信息:
从表对象.外键属性.主表属性
- 关联过滤查询:
模型类名.objects.filter(关联模型类名小写__属性名__运算符=值)
查询结果集(QuerySet)
数据库获取的对象集合,Django调用过滤器方法会返回QuerySet:
all()
、filter()
、exclude()
、order_by()
QuerySet特性:
- 惰性执行:只在使用查询结果时才会执行SQL查询访问数据库
- 缓存:查询结果集会缓存到内存中,下次同样的结果集操作不会访问数据库
- 切片:QuerySet支持切片操作,但是不支持负数索引
分页查询
from django.core.paginator import Paginator
所有分页方法都使用:Paginator 类。它完成了将 QuerySet 拆分为 Page 对象的所有繁重工作。
使用说明
基本使用:分页对象 = Paginator(要分页的结果集, 页数)
执行原生SQL
- 执行原生SQL并返回查询结果集:
类名.objects.raw(SQL语句,参数)
- 直接执行原生SQL:使用数据库连接对象用游标直接操作
from django.db import connections
with connections["数据库名称"].cursor() as cursor:
# 下面是需要直接执行的操作
pass
中间件
- 中间件继承
django.utils.deprecation.MiddlewareMixin
类(其他写法参考官方文档) - 中间件不同方法会在不同阶段被自动调用,具体参考下面的代码:
from typing import Union from django.http import HttpRequest, HttpResponse from django.template.response import TemplateResponse from django.utils.deprecation import MiddlewareMixin class TemplateMiddleware(MiddlewareMixin): def __init__(self, get_response: callable): """中间件初始化方法 :param get_response: """ super().__init__(get_response) def process_request(self, request: HttpRequest): """请求前会自动调用的方法 :param request: 请求对象 :return: """ pass def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse: """响应之前会自动调用的方法 :param request: 请求对象 :param response: 响应对象 :return: 返回值也必须是响应对象 """ pass def process_view(self, request: HttpRequest, view_func: callable, view_args: Union[tuple, list], view_kwargs: dict): """视图函数调用前自动调用的方法 :param request: 请求对象 :param view_func: 视图函数 :param view_args: 传给视图函数的位置参数 :param view_kwargs: 传给视图函数的关键字参数 :return: 它应该返回None或HttpResponse对象。如果它返回None,Django将继续处理这个请求,执行任何其他的process_view() , 然后执行相应的视图。如果它返回HttpResponse对象,Django不会去影响调用相应的视图;它会将响应中间件应用到HttpResponse并返回结果。 """ pass def process_exception(self, request: HttpRequest, exception: Exception) -> Union[None, HttpResponse]: """视图函数抛出异常时会自动调用的方法 :param request: 请求对象 :param exception: 视图函数引发的Exception对象 :return: 当视图引发异常时,Django会调用process_exception()。process_exception()应该返回None或HttpResponse对象。如果它返回一个HttpResponse对象,模板响应和响应中间件将被应用且会将结果响应返回浏览器。否则,就会开始默认异常处理。 """ pass def process_template_response(self, request: HttpRequest, response: TemplateResponse): """视图执行完之后自动调用(了解即可) :param request: :param response: :return: """ pass
- 启用中间件:在
settings.py
文件中将中间件添加到MIDDLEWARE
列表中 - 中间件调用顺序:当
MIDDLEWARE
中定义了多个中间件时,在请求时中间件列表执行顺序是正序,在响应是中间件列表执行顺序是倒序