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】方法

  1. request.get(): 获取GET请求参数的值。
  2. request.post(): 获取POST请求参数的值。
  3. request.get_full_path(): 返回包含查询参数的完整路径。
  4. request.is_secure(): 返回一个布尔值,指示请求是否通过HTTPS协议进行。
  5. request.build_absolute_uri(): 构建并返回请求的绝对URL。
  6. request.get_host(): 返回请求的主机名。
  7. request.get_port(): 返回请求的端口号。
  8. request.get_raw_uri(): 返回原始请求URI。
  9. request.is_ajax(): 返回一个布尔值,指示请求是否是通过Ajax发送的。
  10. 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配置数据库

image-20240312172612314

【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

img

【五】路由层

【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')
  • InMemoryUploadedFileTemporaryUploadedFile 对象并不是真正的文件对象,而是内存中的临时对象或临时文件对象。这些对象的主要作用是临时存储上传的文件内容,而不是直接写入文件系统中

  • chunks() 方法返回一个生成器(generator),每次迭代都会产生一块文件内容的数据。

【3.1】文件对象常用的属性和方法

一些常用的属性包括:

  1. name: 上传文件的名称。
  2. size: 上传文件的大小。
  3. content_type: 上传文件的内容类型。
  4. charset: 上传文件的字符集。
  5. content_type_extra: 上传文件的额外内容类型信息。
  6. file: 上传文件的内容(BytesIO 对象)。

一些常用的方法包括:

  1. read(): 读取文件的内容。
  2. readline(): 读取文件的一行。
  3. chunks(chunk_size=None): 生成器函数,按块读取文件内容。
  4. seek(offset, whence=0): 移动文件指针到指定位置。
  5. close(): 关闭文件。
  6. multiple_chunks(): 检查文件是否分成多个块。
  7. 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源码分析

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添加装饰器

装饰类 | Django 文档 | Django (djangoproject.com)

  • 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 %}

04f99e6e294df660edd2aa69d7e4e041.png

【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将其识别为一个包。
  • 在注册自定义标签时的语法是固定的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】字段参数

常用的字段参数:

  1. verbose_name:字段的人类可读名称,用于在管理界面中显示。
  2. help_text:字段的帮助文本,用于在表单中显示有关字段的提示信息。
  3. null:如果为 True,则数据库中的该字段可以为空(默认为 False)。
  4. blank:如果为 True,则表单中的该字段可以为空(默认为 False)。
  5. default:字段的默认值,如果没有提供值,则会使用该默认值。
  6. primary_key:如果为 True,则该字段被定义为模型的主键(通常不需要手动指定,Django 会自动为 AutoField 设置为主键)。
  7. unique:如果为 True,则该字段的值在整个表中必须是唯一的。
  8. choices:一个可选的选项列表,用于限制字段的值为预定义的一组选项。
  9. max_length:字符串字段的最大长度。
  10. db_index:如果为 True,则为该字段创建数据库索引,以加速查询。
  11. db_column:指定数据库中字段的列名。
  12. db_tablespace:指定字段所属的表空间。
  13. validators:一个验证器函数的列表,用于验证字段的值。
  14. editable:如果为 False,则该字段在模型的管理界面中不可编辑(默认为 True)。
  15. auto_now:如果为 True,则在每次保存对象时,该字段都会被设置为当前时间。
  16. auto_now_add:如果为 True,则只在对象创建时将该字段设置为当前时间,之后不会更新。
  17. 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',
        },
    }
}

关于模型表,更加详细的部分将会在另一篇随笔中详细介绍

posted @ 2024-03-12 22:50  Lea4ning  阅读(16)  评论(0编辑  收藏  举报