Django基础知识点一
Django基础知识点
【零】补充方法
【1】Django项目测试
if __name__ == '__main__':
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'BookSystem.settings')
django.setup()
'''测试代码'''
【2】项目使用模块版本导入与导出
# 查看
pip freeze
# 导出
pip freeze > requirements.txt # requirements文件名可以自行更改,但约定俗称
# 导入
pip install -r requirements.txt # 安装文件中的模块及版本
【一】使用静态文件
【1】配置静态文件
# settings.py
STATIC_URL = 'static/'
STATICFILES_DIRS = [
# 存放静态文件的路径
os.path.join(BASE_DIR, 'static')
【2】加载静态文件
# 前端
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# 加载静态文件中的js文件#}
<script src="{% static 'xxx.js' %}"></script>
{# 加载静态文件中的css文件#}
<link rel="stylesheet" href="{% static 'xxx.css' %}">
</head>
<body>
{#加载静态文件中的文件#}
{% static 'xxx' %}
</body>
</html>
【二】request对象
【1】属性
request.method
: 返回HTTP请求方法,如GET、POST等。request.path
: 返回请求的路径部分。request.GET
: 包含GET请求参数的字典。request.POST
: 包含POST请求参数的字典。request.FILES
: 包含上传文件的字典。request.session
: 返回一个与请求关联的会话对象。request.user
: 返回当前登录用户的对象。request.META
: 包含HTTP请求的元数据的字典,如请求头信息、IP地址等。request.COOKIES
: 包含请求中的cookie的字典。
【2】方法
request.get()
: 获取GET请求参数的值。request.post()
: 获取POST请求参数的值。request.get_full_path()
: 返回包含查询参数的完整路径。request.is_secure()
: 返回一个布尔值,指示请求是否通过HTTPS协议进行。request.build_absolute_uri()
: 构建并返回请求的绝对URL。request.get_host()
: 返回请求的主机名。request.get_port()
: 返回请求的端口号。request.get_raw_uri()
: 返回原始请求URI。request.is_ajax()
: 返回一个布尔值,指示请求是否是通过Ajax发送的。request.session.get()
: 获取会话数据。
【三】ORM(object ralational mapping)
【1】配置数据库
# settings.py
'''django默认使用小型数据库sqlite3'''
DATABASES = {
'default': {
# 选择数据库引擎
'ENGINE': 'django.db.backends.sqlite3',
# 选择库名
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# settings.py
'''MySQL数据库配置'''
DATABASES = {
'default': {
# 选择数据库引擎
'ENGINE': 'django.db.backends.mysql',
# 库名
'NAME': '库名',
# 登录的用户名
'USER': '用户名',
# 用户名对应的密码
'PASSWORD': '密码',
# 主机地址
'HOST': '127.0.0.1',
# 端口,一般是3306
'PORT': 3306
}
}
【1.1】PyCharm配置数据库
【1.2】报错情况
'''django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.'''
- 解决
# 猴子补丁:任意一个文件夹中的 __init__.py
import pymysql
pymysql.install_as_MySQLdb()
# 安装第三方模块
pip install mysqlclient
【2】数据迁移文件
- 在Django中,对数据库操作依赖于
from django.db import models
组件 - 在
models.py
文件中创建表后,需要执行数据迁移使数据对数据库生效
# 创建数据迁移文件
python manage.py makemigration
# 执行数据迁移
python manage.py migrate
# 【注】执行manage.py操作,需要在该文件所在位置执行命令
【3】对应关系
from django.db import models
class TableName(models.Model):
# 字段 = models.字段类型(约束条件)
field1 = models.CharField(max_length=32, unique=True, null=True, verbose_name='描述')
class Meta():
db_table = '自定义表名'
# 每一个实例化类得到的对象可以对应数据库中的记录(或行)。
# 每个对象代表数据库表中的一条记录,并且对象的属性对应表中的字段
【四】请求生命周期流程图
【五】路由层
【1】路由匹配
# urls.py
'''django1.10版本引入了path函数,1.x版本使用正则匹配【url(r'正则/')】'''
from django.urls import path
from views import func
urlpatterns = [
# path('路径/',视图函数)
path('xxx/',views.func)
]
【2】正则匹配
# urls.py
from django.urls import re_path
from views import func
urlpatterns = [
# 正则匹配分为有名分组和无名分组
'''无名分组匹配到的路径在后端可以通过【*args】中的参数接受'''
re_path(r'^正则表达式/',views.func) # 无名分组
'''有名分组匹配到的路径在后端可以通过【**kwargs】或指定【key】接受数据'''
re_path(r'(?P<name>正则表达式)') # 有名分组
]
【3】路径转换器
<int>
:匹配一个整数。<str>
:匹配一个字符串,但不包含路径分隔符/
。<slug>
:匹配一个 Slug,由字母、数字、连字符或下划线组成。<uuid>
:匹配一个 UUID 格式的字符串。<path>
:匹配包含路径分隔符/
的字符串。
# urls.py
'''路径转换器与正则匹配的有名分组类似,且可以作类型转换'''
'''普通的路由匹配拿到的路径都是字符串,而通过路径转换器后端可以拿到指定格式的数据'''
from django.urls import path
from views import func
urlpatterns = [
# < int:id >
path('根路径/< 路径转换器:name >',视图函数)
]
【4】反向解析
- 在 Django 中进行反向解析时,必须要给 URL 模式或视图函数命名
【4.1】无名反向解析
# urls.py
from django.urls import path
from views import func
urlpatterns = [
path('路径/',视图函数,name='view_name')
]
# views.py
from django.shortcuts import HttpResponse, reverse
def func(request):
url = reverse('view_name')
return HttpResponse(url)
# '/view_name/' 可以通过该反向解析的url获取到该name对应的视图函数
<!-- 前端使用反向解析 -->
<body>
<!-- 比较常用于为按钮或链接添加跳转链接,跳转至指定视图函数 -->
<a href='{% url 'view_name'%}'>link</a>
</body>
【4.2】有名反向解析
# urls.py
from django.urls import path,re_path
from views import func
urlpatterns = [
# 路径转换器
path('路径/<int:id>',视图函数,name='view_name'),
# 无名分组
re_path('路径/(?P<bid>(\d+)/)',视图函数,name = 'view_name')
]
# views.py
from django.shortcuts import HttpResponse, reverse
def func(request,**kwargs):
'''当路由中设置为有名时,后端需要设置形参接受,否则会报错'''
url = reverse('view_name',kwargs={k:v})
return HttpResponse(url)
# '/view_name/value/' 可以通过该反向解析的url获取到该name对应的视图函数
<!-- 前端 -->
<body>
<!-- 需要将参数传递放置在view_name后,否则将报错 -->
<a href='{% url 'view_name' value %}'>link</a>
</body>
【5】路由分发
- 为了对路由解耦合,保证代码清晰可读
# urls
from django.urls import path
from django.urls.conf import include
urlpatterns = [
# 一般会为每一个应用程序创建一个urls文件
path('路径/',iuclude('指定文件夹.urls'))
]
【六】视图层
【1】响应三板斧
【1.1】HttpResponse
- 将字符串转换为HttpResponse对象
- 【注】视图函数所返回的对象必须是HttpResponse对象或者渲染的前端页面
# views.py
from django.shortcuts import HttpResponse
def func(request):
return HttpResponse('Hello World!')
【1.2】render
- 返回渲染的前端界面
# views.py
from django.shortcuts import render
def func(request):
return render(request=request,templates_name='前端文件.html',context='上下文')
【1.3】redirect
- 重定向至指定视图函数
# views.py
from django.shortcuts import redirect
def func(request):
return redirect(to='view_name',context='上下文',permanent=301/302)
# permanent可以指定永久重定向【301】还是临时重定向【302】
# 默认302,因为301将会缓存至浏览器,下一次将优先从缓存中获取界面
【2】JsonResponse
- 返回json格式的响应数据
# views.py
from django.http import JsonResponse
def func(request):
data = {
'k':v
}
return JsonResponse(data)
JsonResponse
的其他参数data
: 要转换为 JSON 的数据。默认情况下,由于安全漏洞,在 EcmaScript 5 之前只允许传递dict
对象。有关更多信息,请参见safe
参数。encoder
: 应该是一个 JSON 编码器类。默认为django.core.serializers.json.DjangoJSONEncoder
。safe
: 控制是否只有dict
对象可以被序列化。默认为True
。json_dumps_params
: 传递给json.dumps()
的关键字参数字典
【3】获取文件数据
- form表单中input标签设置type属性为file时,上传的数据需要进一步处理才能获取
<!-- 前端上传数据 -->
<body>
<!-- 指定【enctype】参数 -->
<form action="" method="post" enctype="multipart/form-data">
file: <input type="file" name='filename'>
</form>
</body>
# views.py
# 后端获取数据
def func(request):
if request.method == 'POST':
# 当表单提交数据时,获取到表单中的文件数据
file_obj = request.FILES.get('filename') # 当有多个文件时,根据name数据设置的键取值
# 当前file_obj只是内存中的临时缓存,不能直接写入文件,需要通过【.chunks()】方法
file = file_obj.chunks()
with open('文件路径', mode='wb') as fp:
for data in file:
fp.write(data)
return render(request, '前端页面.html')
-
InMemoryUploadedFile
和TemporaryUploadedFile
对象并不是真正的文件对象,而是内存中的临时对象或临时文件对象。这些对象的主要作用是临时存储上传的文件内容,而不是直接写入文件系统中 -
chunks()
方法返回一个生成器(generator),每次迭代都会产生一块文件内容的数据。
【3.1】文件对象常用的属性和方法
一些常用的属性包括:
name
: 上传文件的名称。size
: 上传文件的大小。content_type
: 上传文件的内容类型。charset
: 上传文件的字符集。content_type_extra
: 上传文件的额外内容类型信息。file
: 上传文件的内容(BytesIO 对象)。
一些常用的方法包括:
read()
: 读取文件的内容。readline()
: 读取文件的一行。chunks(chunk_size=None)
: 生成器函数,按块读取文件内容。seek(offset, whence=0)
: 移动文件指针到指定位置。close()
: 关闭文件。multiple_chunks()
: 检查文件是否分成多个块。temporary_file_path()
: 获取文件的临时文件路径(如果存在)。
【4】CBV视图类
【4.1】FBV和CBV
- CBV(Class-Based Views)和 FBV(Function-Based Views)是 Django 中两种常用的视图编写方式,它们分别基于类和函数。
# views.py
from django.shorcuts import render,HttpResponse
'''CBV视图类需要继承【View类】'''
from django.views import View
def fbv(request):
# FBV基于函数
return HttpResponse('FBV')
class Cbv(View):
# CBV基于类
def get(self,request):
'''当【get请求】调用视图类时执行的代码'''
return HttpResponse('CBV - get')
def post(self,request):
'''当【post请求】调用视图类时执行的代码'''
return HttpResponse('CBV - post')
# urls.py
'''在路由中,FBV与CBV的调用方式有所不同'''
from django.urls import path
from views import fbv,Cbv
urlpatterns = [
# FBV就是平时使用的最多的视图函数
path('路径/',fbv),
# CBV视图类调用时,需要使用【as_view()】方法调用
# 具体原因请看源码分析
path('路径',Cbv.as_view(),name='CBV')
]
【4.2】CBV源码分析
【5】装饰器
【5.1】为FBV添加装饰器
- FBV就是普通的函数,所以与给函数加装饰器语法一致
# 装饰器
def auth(func):
def inner(request,*args,**kwargs):
# 需要注意,因为视图函数的第一个对象都是request,所以一般情况下将第一个形参设置为request
# 当然,如果愿意,也可以从【args[0]】中获取
res = func(request,*args,**kwargs)
return res
return inner
# 加了装饰器视图函数
@auth
def func(request):
return HttpResponse('oi')
【5.2】为CBV添加装饰器
- CBV视图类,因为是类,当调用普通的装饰器时,第一个参数将会错乱,可能时
self
也可能时cls
,request对象将不太好寻找 - 为CBV添加装饰器需要借助
from django.utils.decorators import method_decorator
组件
【5.2.1】加装饰器在类上
# 装饰器
def auth(func):
'''装饰器函数的创建是一致的'''
def inner(request,*args,**kwargs):
res = func(request,*args,**kwargs)
return res
return inner
@method_decorator(decorator='装饰器名',name='需要加装装饰器的函数')
class Cbv(View):
def get(self, request):
'''当【get请求】调用视图类时执行的代码'''
return HttpResponse('CBV - get')
def post(self, request):
'''当【post请求】调用视图类时执行的代码'''
return HttpResponse('CBV - post')
【5.2.2】加装饰器在函数上
class Cbv(View):
@method_decorator(decorator='装饰器名')
def get(self, request):
'''当【get请求】调用视图类时执行的代码'''
return HttpResponse('CBV - get')
@method_decorator(decorator='装饰器名')
def post(self, request):
'''当【post请求】调用视图类时执行的代码'''
return HttpResponse('CBV - post')
【5.2.3】加装饰器在函数dispatch
- 根据源码我们可以看到在执行我们写的方法前,会先执行dispatch方法,所以如果重写父类中的dispatch方法,并添加装饰器,那么在我们视图类中的所有方法都可以加上装饰器
class Cbv(View):
def get(self, request):
'''当【get请求】调用视图类时执行的代码'''
return HttpResponse('CBV - get')
def post(self, request):
'''当【post请求】调用视图类时执行的代码'''
return HttpResponse('CBV - post')
@method_decorator(decorator='装饰器名')
def dispatch(self, request, *args, **kwargs):
'''不对dispatch作其他操作,直接继承父类中的方法'''
return super().dispatch(request, *args, **kwargs)
【5.4】当装饰器有多个时
'''当装饰器有多个时,可以构建一个列表或元组'''
decorators = [never_cache, login_required]
# 传参时将上述的列表或元组传入即可
@method_decorator(decorators, name='dispatch')
class ProtectedView(View):
template_name = 'secret.html'
【七】模板层
【0】模板文件(templates)
- 想要访问到项目中的模板文件,需要在settings.py中配置路径
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
# 需要在此配置路径
os.path.join(BASE_DIR,'模板文件夹'),
]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
],
},
},
]
【1】模板基础语法
- 模板语法的渲染基于后端向前端返回数据
# views.py
def func(request):
'''需要注意,后端向前端发送数据,基于上下文参数,也就是【context】'''
变量名=变量值
'''context参数接受一个字典传给前端,只有变量是不可以的'''
dict1 = {k:v}
return render(request,'前端文件.html',context=dict1)
{{ key }}
<!-- 前端页面上将会根据k渲染出对应的值 -->
【补】locals()
- 在函数中,可以使用
locals()
函数获取到当前局部名词空间的所有变量,且是字典格式 - 所以如果变量较多,可以使用
context=locals()
,但是需要慎用
【2】模板语法变量类型
<!-- 前端 -->
<body>
<!-- 都会根据键渲染出对应的值 -->
<p>str : {{ a }}</p>
<p>int : {{ b }}</p>
<p>float : {{ c }}</p>
<p>list : {{ d }}</p>
<p>tuple : {{ e }}</p>
<p>dict : {{ f }}</p>
<p>set : {{ g }}</p>
<p>bool : {{ h }}</p>
<p>func_no_return : {{ i }}</p>
<p>func_has_return : {{ j }}</p>
</body>
# views.py
def func1():
'''函数将会渲染对应的返回值,如果没有将是None'''
print(a)
def func2():
return 'hello world'
def page(request, *args, **kwargs):
d1 = {
'a': '字符串',
'b': 999,
'c': 99.999,
'd': [1, 2, 3],
'e': (1, 2, 3),
'f': {1: 2},
'g': {1, 2},
'h': True,
'i':func1,
'j':func2
}
return render(request, "index.html", context=d1)
【3】模板语法取值
- 如果传递的是对象,是可以在模板语法中通过【.】语法,获取属性
【注】点语法的查找顺序
- 点在模板渲染中具有特殊的意义。变量名中的点表示 查找。具体来说,当模板系统遇到变量名中的点时,它将按照以下顺序尝试进行查找:
-
词典查找。例如:
foo["bar"]
-
属性查找。例如:
foo.bar
-
列表索引查找。例如:
foo[bar]
-
- 请注意,像
{{ foo.bar }}
这样的模板表达式中的“bar”将被解释为一个字面字符串,而不是使用变量“bar”的值
<body>
<p>类: {{ MyClass }}</p>
<p>对象: {{ obj }}</p>
<p>对象的普通方法: {{ obj.get_self }}</p>
<p>对象的静态方法: {{ obj.get_func }}</p>
<p>类绑定方法: {{ obj.get_class }}</p>
</body>
def page(request, *args, **kwargs):
# 类
class MyClass(object):
# 普通方法
def get_self(self):
print('my_self')
return 'my_self'
# 静态方法
@staticmethod
def get_func():
print('my_func')
return 'my_func'
# 类绑定方法
@classmethod
def get_class(cls):
print('my_class')
return 'my_class'
# 实例化对象
obj = MyClass()
return render(request, "index.html", context=locals())
【4】过滤器{{ variable|filter }}
- 基本语法
{{ variable|filter }}
- 过滤器可以多个一起使用,如
{{ variable|filter1|filter2|... }}
- 【注】有些过滤器允许携带一个参数,过滤器、冒号、参数之间不能有空格,否则将会报错
过滤器 | 说明 |
---|---|
add | 加法 |
addslashes | 添加斜杠 |
capfirst | 首字母大写 |
center | 文本居中 |
cut | 切除字符 |
date | 日期格式化 |
default | 设置默认值 |
default_if_none | 为None设置默认值 |
dictsort | 字典排序 |
dictsortreversed | 字典反向排序 |
divisibleby | 整除判断 |
escape | 转义 |
escapejs | 转义js代码 |
filesizeformat | 文件尺寸人性化显示 |
first | 第一个元素 |
floatformat | 浮点数格式化 |
force_escape | 强制立刻转义 |
get_digit | 获取数字 |
iriencode | 转换IRI |
join | 字符列表链接 |
json_script | 生成script标签,带json数据 |
last | 最后一个 |
length | 长度 |
length_is | 长度等于 |
linebreaks | 行转换 |
linebreaksbr | 行转换 |
linenumbers | 行号 |
ljust | 左对齐 |
lower | 小写 |
make_list | 分割成字符列表 |
phone2numeric | 电话号码 |
pluralize | 复数形式 |
pprint | 调试 |
random | 随机获取 |
rjust | 右对齐 |
safe | 安全确认 |
safeseq | 列表安全确认 |
slice | 切片 |
slugify | 转换成ASCII |
stringformat | 字符串格式化 |
striptags | 去除HTML中的标签 |
time | 时间格式化 |
timesince | 从何时开始 |
timeuntil | 到何时多久 |
title | 所有单词首字母大写 |
truncatechars | 截断字符 |
truncatechars_html | 截断字符 |
truncatewords | 截断单词 |
truncatewords_html | 截断单词 |
unordered_list | 无序列表 |
upper | 大写 |
urlencode | 转义url |
urlize | url转成可点击的链接 |
urlizetrunc | urlize的截断方式 |
wordcount | 单词计数 |
wordwrap | 单词包裹 |
yesno | 将True,False和None,映射成字符串‘yes’,‘no’,‘maybe’ |
【5】模板标签{% tags %}
【5.1】for循环
- for ... endfor
{% for obj in obj_all %}
{# 循环体内的代码 #}
{% endfor %}
- for .. empty ... endfor
{% for obj in obj_all %}
{# 循环体内的代码 #}
{% empty %}
{# 如果obj_all是空值,执行该段代码 #}
{% endfor %}
【5.2】if条件判断
- if .. elif ... else ... endif
{% if condition %}
{# condition成立的代码 #}
{% elif condition2 %}
{# condition2成立的代码 #}
{% else %}
{# 都不成立的代码 #}
{% endif %}
【5.3】forloop{% forloop.属性 %}
Variable | Description |
---|---|
forloop.counter |
当前循环的索引值(从1开始) |
forloop.counter0 |
当前循环的索引值(从0开始) |
forloop.revcounter |
当前循环的倒序索引值(从1开始) |
forloop.revcounter0 |
当前循环的倒序索引值(从0开始) |
forloop.first |
当前循环是不是第一次循环(布尔值) |
forloop.last |
当前循环是不是最后一次循环(布尔值) |
forloop.parentloop |
本层循环的外层循环 |
【5.3】with{% with name=... %}
- 用于在模板中创建变量。作用是将一个复杂的表达式或对象存储到一个变量中,以便在模板的其他地方重复使用
{% with name=…… %}
{% endwith %}
【6】自定义标签
- 可以方便地将一段 HTML 片段封装成一个可复用的模板标签。
【6.1】inclusion_tag
- 共有三个文件
- main.html : 最终渲染的数据
- middle.html :创建HTML片段
- mytags.py : 创建自定义标签
- 这三个文件的文件名自己定义即可,没有硬性规定
【注】硬性的文件/变量命名要求
- 自定义标签所在的文件夹名为
templatetags
- Django要求自定义模板标签必须放置在名为
templatetags
的文件夹下。 - 这个文件夹必须位于你的应用程序的顶层目录中,并且必须包含一个名为
__init__.py
的空文件,以便Python将其识别为一个包。
- Django要求自定义模板标签必须放置在名为
- 在注册自定义标签时的语法是固定的
register = template.Library()
# mytags.py
from django import template
# 注册语句是固定的,变量名必须叫register,否则可能会报错或识别不到
register = template.Library()
@register.inclusion_tag('middle.html') # 【middle.html】是创建html片段的文件
def tag(num):
# 这里可以编写处理逻辑,然后将结果传递给模板
l1 = [i for i in range(num)]
# 可以用locals,也可以构建一个字典,因为是传递上下文数据
return locals()
<!-- middle.html -->
{#在这里创建html片段#}
{% for foo in l1 %}
{# 这里可以识别到函数返回的上下文数据,并对数据进行处理#}
<p>{{ foo }}</p>
{% endfor %}
<!-- main.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>最终渲染界面</h1>
{% load 文件名 %}
{% 函数名 参数 %}
{% load mytags %}
{% tag 5 %}
</body>
</html>
【6.2】simple_tag
-
simple_tag:
- 用于创建简单的模板标签,生成的标签通常返回一个字符串。
- 被装饰的函数需要返回一个字符串,这个字符串将被直接插入到模板中。
- 可以接受任意数量的参数。
- 适合于处理简单的逻辑,例如格式化文本或生成特定格式的链接。
-
与inclusion_tag不同,simple_tag不需要三个文件,只需要
mytags.py
文件和main.html
文件即可
文件名不一定非要叫这个名字,只是显得逻辑清晰一些
# mytags.py
from django import template
register = template.Library()
@register.simple_tag(name='simple_tag') # 前端加载时,根据name参数的值加载即可
def simple_tag(*args):
txt = '|'.join(args)
return txt
<body>
<h1>最终渲染界面</h1>
{% 函数名 '参数1' '参数2' '参数3' %}
{% simple_tag 'a' 'b' 'c' %}
</body>
</html>
【7】模板继承
- 在html文件中使用
{% block 块名 %} + {% endblock %}
,就为其他文件创建了一个可改变的区域,称为母版 - 其他文件可以通过声明
{% extends '文件.html' %}
继承母版文件,称为子版 - 子板可以通过
{% block 块名 %} + {% endblock %}
修改指定的区域,而不改变其余区域的样式
<!-- 母版 -->
<head>
<meta charset="UTF-8">
{#模板标签不限于位置,写在哪里都可以,只要知道,子板可以通过指定的名称会替换掉母版中的内容#}
{#如果没有被子板声明的区域,将会正常渲染母版中的内容#}
{% block content-title %}
<title>Title</title>
{% endblock %}
</head>
<body>
<h2>Hello world</h2>
{% block content-main %}
<h1>这是母版</h1>
{% endblock %}
</body>
<!-- 子版 -->
{% extends '母版.html' %}
{#声明继承的母版文件#}
{% block content-title %}
{# 根据区域名替换母版中的内容#}
<title>子版</title>
{% endblock %}
{% block content-main %}
{# 根据区域名替换母版中的内容#}
<h1>这是子版</h1>
{% endblock %}
【八】模型层
【0】常用字段及参数
【0.1】字段
字段方法 | 功能说明 |
---|---|
AutoField() | 从1开始自增1的整数类型字段id,在模型里没有显式定义该属性的情况下,Django自动增加该字段到新表结构里。默认情况下该字段同时是主键字段。 |
BigAutoField() | 64位自增整数字段,功能类似AutoField(),唯一区别支持的数字范围更大 |
IntegerField() | 整数类型字段,取值范围在-2147483648到2147483647,支持所有数据库。 |
BigIntegerField() | 64位整数类型字段,功能类似IntegerField(),唯一区别支持的数值范围更大 |
BinaryField() | 存储原始二进制数据类型字段。 |
BooleanField() | 布尔类型字段,默认值是None,若接受null,则改NullBooleanField()方法。 |
CharField() | 字符串类型字段,使用该方法时,必须指定参数max_length值,表 示该字段可以接受的最长字符串长度。 |
DateField() | 日期类型字段,对应 Python语言的datetime.date对象值。 |
DateTimeField() | 日期时间类型字段 ,对应Python语言的datetime.datetime对象值 |
DecimalField() | 固定小数精度的数值类型字段,常常用于存储资金相关的数。 |
FloatField() | 浮点类型字段,对应python语言的float类型数值。小数精度有限,单精度保持7位,双精度保持15位。 |
FileField() | 上传文件类型字段, |
ImageField() | 图像类型字段,继承了FileField()的所有属性、方法,使用该字段需 要提前安装pillow库。pip install pillow。 |
TextField() | 长文本字段。 |
SmallIntegerField() | 短整型字段,数值范围位-32768到32767,适用于所有数据库系统。 |
TimeField() | 时间字段,对应python语言的datetime.time对象值。 |
DurationField() | 持续时间类型字段,对应python语言的timedelta对象值。 |
【0.2】字段参数
常用的字段参数:
- verbose_name:字段的人类可读名称,用于在管理界面中显示。
- help_text:字段的帮助文本,用于在表单中显示有关字段的提示信息。
- null:如果为 True,则数据库中的该字段可以为空(默认为 False)。
- blank:如果为 True,则表单中的该字段可以为空(默认为 False)。
- default:字段的默认值,如果没有提供值,则会使用该默认值。
- primary_key:如果为 True,则该字段被定义为模型的主键(通常不需要手动指定,Django 会自动为 AutoField 设置为主键)。
- unique:如果为 True,则该字段的值在整个表中必须是唯一的。
- choices:一个可选的选项列表,用于限制字段的值为预定义的一组选项。
- max_length:字符串字段的最大长度。
- db_index:如果为 True,则为该字段创建数据库索引,以加速查询。
- db_column:指定数据库中字段的列名。
- db_tablespace:指定字段所属的表空间。
- validators:一个验证器函数的列表,用于验证字段的值。
- editable:如果为 False,则该字段在模型的管理界面中不可编辑(默认为 True)。
- auto_now:如果为 True,则在每次保存对象时,该字段都会被设置为当前时间。
- auto_now_add:如果为 True,则只在对象创建时将该字段设置为当前时间,之后不会更新。
- upload_to:用于 FileField 和 ImageField 的上传文件的存储路径。
【1】数据的增删改查
- 在ORM中提到,每一个实例化类得到的对象可以对应数据库中的记录(或行)。
- 当我们操作记录时,就需要先实例化类,得到对象
- 另外,ORM操作支持链式操作,也就是【obj.方法.方法.方法]
【1.1】增加数据
from models import Table
# 先从模型文件中导入模型表
# 【1】在实例化对象时,将属性值添加
obj = Table(字段名=字段值)
obj.save()
# 【2】通过点属性更改属性值
obj = Table()
# 属性名 = 属性值
Table.字段名 = 字段值
# 保存记录
obj.save()
- 上述需要两部操作,在模型表中,有一个更简便一些的方法,就是通过
obj.objects.方法
实现一些模型表数据的操作,相当于封装(?),我不太确定具体是怎么实现的 - 在 Django 中,每个模型类都有一个默认的 Manager 对象,可以通过
objects
属性来访问。这个 Manager 对象提供了一些用于查询数据库的方法,比如all()
、filter()
、exclude()
等。
obj = Table.objects.create(字段名=字段值)
# 等价于上述的新增数据
# 并且返回的值,是创建出来已经存在与数据库中的对象
【1.1.1】批量插入数据bulk_create
# 当我们需要插入大量数据的时候,可以使用bulk_create方法
# 可以提高出入数据的效率
obj_list = []
for i in range(100000):
# 先生成对象
obj = Table(字段名=字段值)
# 将对象放入一个列表中
obj_list.append(obj)
Table.objects.bulk_create(obj_list)
【1.2】删除数据
# 根据过滤条件删除指定的数据
Table.objects.filter(过滤条件).delete()
'''或者先拿到对象,再删除该对象'''
obj = Table.objects.filter(过滤条件)
obj.delete()
【1.3】修改数据
# 根据过滤条件更新指定的数据
Table.objects.filter(过滤条件).update(字段名=字段值)
【1.4】查询数据
# 获取所有对象
Table.objects.all()
# 获取符合条件的对象 返回的类型是queryset 如果需要对对象进行操作 需要遍历循环
Table.objects.filter(过滤条件)
# 获取一条符合条件的数据 返回的类型是obj对象
Table.objects.get(条件)
【补】查看原生sql语句
- 【queryset对象】才可以使用
.query
obj = Table.objects.filter(条件)
print(obj.query)
- 所有sql语句都可以使用
- 需要在settings.py文件中修改配置
# settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
关于模型表,更加详细的部分将会在另一篇随笔中详细介绍