Django的学习之路~

1. MVT模型

Django模型的基本概念:

M(Model)负责数据与规则,V(View)负责业务与流程,T(Template)负责展示。

View(视图):真正的大脑

在 Django 中,View 并不是页面,而是:

  • 接收 HTTP 请求

  • 调用 Model 处理数据

  • 决定返回什么响应(HTML / JSON / 重定向)

如果用一句话概括:
View 是请求与响应之间的决策者。

Model(模型):世界的事实陈述者

Model 是你对现实世界的抽象说明书。

在 Django 里,Model 通常就是一堆 Python 类,用来描述:

  • 表结构(字段、类型)

  • 数据约束(唯一、非空、外键)

  • 与数据库交互的规则

它不关心页面长什么样,也不关心请求从哪来,只做一件事:
定义数据是什么,以及数据之间的关系。

Template(模板):克制的表现主义者

Template 只负责一件事:
把数据渲染成用户能看的东西。

2. Django的安装和简单初体验

复制代码
## django下载安装
pip install django==3.1.2

## 指令创建
django-admin startproject zhibang(项目名称)

## 创建应用
python manage.py startapp login(应用app名称)

在项目的settings.py文件中

复制代码
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login'  ## 加上应用名称
]

在url.py文件中设置路径和函数的对应关系

复制代码
from django.contrib import admin
from django.urls import path
from login import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/', views.home),
]

在views.py文件中写视图函数

复制代码
from django.shortcuts import render

def home(request): ## 参数名称业内一般都写成request,
    print(request.path)
    current_name = 'zhibang'
    ret =   render(request,'home.html',{'username':current_name})
    return ret

templates文件夹中创建一个home.html文件

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>尊贵的{{username}}用户,欢迎您!</h1>
</body>
</html>

在settings.py文件中加上如下配置

复制代码
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [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',
            ],
        },
    },
]

浏览器访问

http://127.0.0.1:8000/home

3. Django框架的url 模块

在路由模块中需要注意的点

复制代码
urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/',views.login),
    path('index/',views.index)
]

## 1. 路径的前置导航斜杠(对应根路径那个),不需要写,django自动加上
## 2. http://127.0.0.1:8000/index 当我们访问django的url路径时,如果请求路径最后没有写/,那么django会发一个重定向的响应,告诉浏览器,加上/再来访问我
## 3. 在settigns.py配置文件中修改:
# 默认为True, 当值为True时,django需要请求路径后面加上斜杠,如果请求没有加,那么响应301重定向,让浏览器街上斜杠重新请求
APPEND_SLASH = True

url分组

复制代码
urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/',views.login),
    path('index/<int:year>/',views.index)  ## django的版本默认使用了关键字传参了。抛弃了以前的正则表达式的书写方式
] 

路由分发

django中可以使用路由分发来来为url统一的管理起来。每一个 HTTP 请求进来,它干的第一件事不是执行业务逻辑,而是先问一句:这条 URL,到底该谁来处理?然后去找到对应的应用下面处理业务逻辑问题

复制代码
### 创建app01,app02,app03三个应用

## 在总项目下的url.py中只要写入app的应用就可以了
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
    path('admin/', admin.site.urls),
    path('app01/',include('app01.urls')),
    path('app02/',include('app02.urls')),
    path('app03/',include('app03.urls')),
]

# 在每个应用下创建urls.py文件,写每个应用自己的路径
# app01/urls.py
from app01 import views
from django.urls import path, include
from  app01 import  views
urlpatterns = [
    path('index/',views.index,name='index')
]
# app01/view.py
from django.shortcuts import render,HttpResponse

# Create your views here.
def index(resquest):
    return HttpResponse('app01 ok!')

# app02/urls.py
from  django.urls  import  include,path
from app02 import  views
urlpatterns = [
    path('index/',views.index,name='index')
]
# app02/view.py
from django.shortcuts import render,HttpResponse

# Create your views here.
def index(resquest):
    return HttpResponse('app02 ok!')

# app03/urls.py
from django.urls import path,include
from app03 import  views
urlpatterns = [
    path('index/',views.index,name='index')
]
# app03/view.py
from django.shortcuts import render,HttpResponse

# Create your views here.
def index(request):
    return HttpResponse('app03 ok')

#当用户访问的路径为 /app01/index/那么会先找到总路由,总路由先匹配路径前缀,匹配好之后,就找到对应的应用下面的urls.py文件中的路径来匹配剩余部分路径,然后执行对应的视图函数.

名称空间

复制代码
## 总路由写法
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
    path('admin/', admin.site.urls),
    path('app01/',include('app01.urls')),
    path('app02/',include('app02.urls')),
    path('app03/',include('app03.urls')),
]

# 在子应用中需要用app_name 定义
app_name = "app01"
urlpatterns = [
    path('index/',views.index,name='index')
]
# 在view.py的视图函数后需要定义
from django.shortcuts import render,HttpResponse,reverse
def index(resquest):
    # 命名空间名称:别名名称
    print(reverse('app02:index')) 
    return HttpResponse('app02 ok!')

4. Django框架的view 模块

request方法

复制代码
from django.shortcuts import render,HttpResponse,redirect
## request 常用的属性
def login(request):
	print(request)  #<WSGIRequest: GET '/login/?a=1&b=2'> WSGIRequest类的实例化对象
	print(request.method)
	print(request.POST)
	print(request.GET)  # request.GET.get('a')  == 1
	print(request.path)  #当前请求路径
	print(request.get_full_path())  #当前请求路径包含查询参数
	print(request.META)  #所有请求头的信息 {''HTTP_USER_AGENT':'asdfasdfasdf',....}
	# request.META 字典类型数据,所有的请求头的键都加上了一个HTTP_键名称
	return HttpResponse('ok')

redirect 方法

复制代码
## view
## 模拟一个用户登录功能,用户提交用户名,登录成功后显示首页
from django.shortcuts import render,HttpResponse,redirect
def login(request):
    currnet_user = "志邦"
    ret = render(request,'login.html',{'username':currnet_user})
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        username = request.POST.get('username')
        if username == 'zhibang':
            return redirect('home')
            #return  render(request,'home.html')
def home(request):
    book = '书本'
    return  render(request,'home.html',{'book': book})

//登录页
<form action="" method="post">
    {% csrf_token %}
    <input type="text" name="username">
    <button>提交</button>
</form>

<h1>
    这是一个首页{{ book }}
</h1>

urls

复制代码
# 这里我写了两个路径,一个是index,另一个home,name的参数最好指定为home这样redirect后面才能找到具体的路径
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/',views.login),
    path('home/',views.home,name='home')
]

CBV和FBV

FBV (Function-Based View,基于函数的视图)。一个请求进来,走进一个函数,返回一个响应。逻辑像水管一样直来直去。我上面写的例子都是基于FBV的方式来运行的

CBV(Class-Based View,基于类的视图) 。把一次请求,拆成多个可复用、可覆盖的步骤。

轻度体验一下:

urls.py 路由文件的写法

复制代码
urlpatterns = [
...
## 除了路径别的都是固定写法
    path('book/',views.Bookview.as_view()),
...
]

视图部分写法

复制代码
from django.views import View
class BookView(View):
	# 通过反射获取到请求方法对应的类中的方法来执行
	def get(self,request):
		return HttpResponse('ok')
	# 需要处理什么请求方法,就写对应名称的方法

在 Django 的 CBV 里,所有请求都会先进入 dispatch()。它的职责不是干活,而是分发任务。可以把它想成前台接待:"你是 GET?那走这边。你是 POST?那走那边。"

复制代码
def dispatch(self, request, *args, **kwargs):
    ## request.method 是 'GET'、'POST' 这种大写字符串。lower() 后变成 'get','post'。
    ## self.http_method_names 在 Django 的 View 里,默认是 ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    if request.method.lower() in self.http_method_names: #get
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)  # HttpResponse('ok')

5. Django框架的Templates 模块

模板渲染

{{变量}}

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
<h2>{{ hobby.0 }}</h2>      <!-- 万能的据点好 -->
<h2>{{ d1.a }}</h2>
<h2>{{ a.my_hobby }}</h2>   <!-- 调用对象的方法时,不能加括号,所以不能调用有参数的方法 -->
</body>
</html>

过滤器

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>{{ hobby|length }}</h2>
<h2>{{ xx|default:'啥也不是' }}</h2> <!-- 当xx为空或者后台没有给这个数据时,会显示默认值 -->
<h3>{{ file_size|filesizeformat }}</h3> <!-- 显示文件大小 -->
<h3>{{ ss|slice:'0:5' }}</h3>
<h3>{{ now|date:'Y-m-d H:i:s' }}</h3>
<h2>{{ a_tag|safe }}</h2>
<h2>{{ aa|truncatechars:'8' }}</h2> <!-- 截断字符,注意8包含了三个点 -->
<h2>{{ aa|truncatewords:'2' }}</h2>  <!-- 以空格做个截断符号,截断单词,2不包含那三个点 -->
</body>
</html>

6. Django框架的orm 模块

在没有 ORM 的世界里,你要亲手写 SQL:建表、查数据、拼字符串、防 SQL 注入、处理游标和连接释放。

Django ORM 的目标很明确:让 80% 的业务查询,不再需要你直接写 SQL

它通过三个核心概念完成这件事:模型(Model)、查询集(QuerySet)、映射关系

orm配置连接mysql

复制代码
## 1. 安装pymysql库
pip install -y pymysql

## 2. 在项目的主目录下__init__.py文件中引入
import  pymysql
pymysql.install_as_MySQLdb()

修改settings.py配置文件

复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  ## backends后面修改为你要连接哪种类型的数库
        'NAME': 'django',         ## 这里指定你要连接的数据库名称
        'HOST': '192.168.0.50',   ## 数据库的地址
        'PORT': 3306,             ## 数据库的端口
        'USER': 'root',           ## 数据库的用户名
        'PASSWORD': '123'         ## 数据库的密码
    }
}

在应用文件夹的models.py文件中创建数据,这里我只是在举例创建,Book生成的表名称为 应用名称_模型类名小写

复制代码
from django.db import models

# Create your models here.
class Book(models.Model):
    id = models.AutoField(primary_key=True) ## 这是主键自增,如果你不设置的话django也会自动帮你加上的
    title = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.CharField(max_length=100)

数据库同步(迁移)指令

复制代码
python manage.py makemigrations
python manage.py migrate

6.1 数据库记录的增删改查-单表

增加

复制代码
from app01 import models
## 方式一,用save()的方法增加记录
def query(request):
    new_book = models.Book(
        title = "西游记",
        price = 19.9,
        pub_date = '2022-09-04',
        publish = '清华大学出版社'
    )
    new_book.save()
    return  HttpResponse('ok')

## 方式二,create方法的返回值为 新添加的数据的模型类对象
def query(request):
    new_book = models.Book.objects.create(
        title = '三国演义',
        price = '20.9',
        pub_date= '2022-09-14',
        publish='北京大学出版社'
    )
    print(new_book.title)  ## 通过模型类对象,直接获取属性对应的值
    print(new_book.price)
    return  HttpResponse('ok')

## 方式三 批量添加
def query(request):
    obj_list = []
    for i in range(5):
        book_list = models.Book(
            title = '水浒传{}'.format(i),
            price = '35.{}'.format(i),
            pub_date = '2024-08-08',
            publish = '复旦大学出版社'
        )
        obj_list.append(book_list)
    models.Book.objects.bulk_create(obj_list)  ## bulk_create 批量添加
    return  HttpResponse('ok')

查询

复制代码
def query(request):
    book_obj = models.Book.objects.all() ## queryset  类似于列表 
    print(book_obj)

    book_objs = models.Book.objects.filter(id=3)   ##  条件查询 结果为queryset类型数据
    print(book_objs)

    book_objs2 = models.Book.objects.filter()     ##  filter没有加条件,和all一样的效果
    print(book_objs2)

    book_objs3 = models.Book.objects.get(id=2)   ## 条件查找 结果为: 模型类对象,但是get方法的查询结果有要求,有且只能有一条
    print(book_objs3.title)
    return  HttpResponse('ok')

# exclude排除
	# 返回结果为queryset类型数据,通过objects控制器可以调用,queryset类型数据也能调用
	# obj_list = models.Book.objects.exclude(id=2)
	# obj_list = obj_list.filter(title='少年阿宾1')
	# obj_list = obj_list.all()
	# obj_list = models.Book.objects.exclude(id=2).filter(title__contains='少年').exclude(id=5)

# order_by 排序
	# 返回结果为queryset类型数据,queryset类型数据可以调用这个方法
	# obj_list = models.Book.objects.all().order_by('-id')   #-id加个-号表示按照该字段降序排列, desc  asc
	# '''select * from app01_book order by id desc;'''
	# obj_list = models.Book.objects.all().order_by('price', '-id') #按照价格升序排列,价格相同的按照id降序排列

# reverse()
	# 翻转必须在排序数据的基础上
	# 返回结果为queryset类型数据,queryset类型数据可以调用这个方法
	# obj_list = models.Book.objects.all().order_by('-id').reverse()

# count
	# queryset类型数据可以调用这个方法,返回值为数字
	# obj_list = models.Book.objects.all().count()

# first\last
	# queryset类型数据可以调用这个方法,返回值为模型类对象
	# obj_list = models.Book.objects.all().first()
	# obj_list = models.Book.objects.all()[0]
	# obj_list = models.Book.objects.all().last()

# exists
	# 判断查询结果是有数据
	# queryset类型数据可以调用这个方法
	# obj_list = models.Book.objects.all().exists()  #判断是否有数据的效率高,只找一条记录 limit 1

# values
	# 可以获取指定字段数据
	# objects可以调用, queryset也能调用,返回结果还是queryset,内容为一个个字典数据
	# obj_list = models.Book.objects.values('title', 'price')
	# obj_list = models.Book.objects.filter(id=5).values('title', 'price')

# values_list
	# 可以获取指定字段数据,返回结果还是queryset,内容为一个个元组数据
	# obj_list = models.Book.objects.values_list('title', 'price')
	# obj_list = models.Book.objects.filter(id=5).values_list('title', 'price')

# distinct 去重
	# 一般配合values和values_list来使用
	obj_list = models.Book.objects.values('price').distinct()

删除

复制代码
models.Book.objects.filter(id=3).delete()  queryset类型数据可以调用delete方法删除查询结果数据
models.Book.objects.get(id=4).delete()  模型类对象也可以调用delete方法删除数据

修改

复制代码
def query(request):
## 方式一 通过queryset类型数据修改
	models.Book.objects.filter(id=5).update(
		price=20,
		title='xxxx'
	)
	models.Book.objects.get(id=5).update(  #报错:模型类对象不能调用update方法
		price=30,
	)    
# 修改方式2  通过模型类对象来修改
ret = models.Book.objects.get(id=5)
	ret.price = 30
	ret.title = '阿甘正传'
	ret.save()
    return  HttpResponse('ok')

基于双下划线的模糊查询

复制代码
# 查询书名以少年开头的哪些书
def query(request):
	# obj_list = models.Book.objects.filter(title__startswith='少年')  #以什么开头
	# obj_list = models.Book.objects.filter(title__endswith='梅') #以什么结尾
	# obj_list = models.Book.objects.filter(title__startswith='p')  #区分大小写
	# obj_list = models.Book.objects.filter(title__istartswith='p')  #不区分大小写
	# obj_list = models.Book.objects.filter(title__contains='th') #包含
	# obj_list = models.Book.objects.filter(title__icontains='th') #包含 不区分大小写

	# obj_list = models.Book.objects.filter(price__gt=15)  大于
	# obj_list = models.Book.objects.filter(price__gte=15)  大于等于
	# obj_list = models.Book.objects.filter(price__lt=15)  小于
	# obj_list = models.Book.objects.filter(price__lte=15)  小于等于

	# obj_list = models.Book.objects.filter(price=15 or price=18 or price=30)
	# obj_list = models.Book.objects.filter(price__in=[15,18,30])  价格等于15或者等于18或者等于30的书籍
	# obj_list = models.Book.objects.filter(price__range=[15, 20])  #价格大于等于15并且小于等于20, between and

	# obj_list = models.Book.objects.filter(id=10, price=15)  #逗号连接的查询条件就是and的关系
	# obj_list = models.Book.objects.filter(pub_date__year='2020')  #2020年的所有书籍
	# obj_list = models.Book.objects.filter(pub_date__year='2020',pub_date__month='11')  #2020年11月份的所有书籍
	# obj_list = models.Book.objects.filter(pub_date__year='2020',pub_date__month='11',pub_date__day='25')  #2020年11月5号的所有书籍
	# obj_list = models.Book.objects.filter(pub_date='2020-11-25')  #2020年11月5号的所有书籍
    return  HttpResponse('ok')

6.2 数据库记录的增删改查-多表

创建多表查询的数据库表字段

复制代码
from django.db import models
# 作者表,和作者详情表是一对一的对应关系,OneToOneField 写在任意一边都可以
class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    au = models.OneToOneField(to="AuthDetail", to_field='id', on_delete=models.CASCADE) 
    ## 另一种写法
    # au = models.OneToOneField("AuthDetail",db_constraint=False,on_delete=models.CASCADE) 
    ## db_constraint=False取消foreign key的强制约束效果,还可以继续使用orm的提供的属性或者方法来操作关系记录  
# 作者详情表
class AuthDetail(models.Model):
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)

## 出版社表
class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
## 书籍表,和出版社表是一对多的关系,ForeignKey 需要写在多的那张表上,和作者表是多对多的关系,写在任意一边即可.
class Book(models.Model):
    title = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publishs = models.ForeignKey('Publish',on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

增加

复制代码
## 一对一的关系添加
def query(request):
	ret = models.AuthDetail.objects.create(
    birthday='2000-12-12',
    telephone='122',
    addr='苏州'
    )
    models.Author.objects.create(
        name='志邦',
        age=18,
        # au_id = ret.id  如果用的是属性名称_id,那么值为关联记录的id值
        au=ret,  #如果写属性名称来添加关系数据,那么值为关联记录的模型类对象
    )
    return  HttpResponse('ok')

## 一对多的关系添加
    ## 第一种写法,
    pub_obj = models.Publish.objects.get(id=2)
    models.Book.objects.create(
        title='春秋',
        price=39.9,
        pub_date='2022-10-20',
        publishs=pub_obj  #如果写属性名称来添加关系数据,那么值为关联记录的模型类对象
    )
    return  HttpResponse('ok')
    ## 第二种写法
    models.Book.objects.create(
        title='三体',
        price=39.9,
        pub_date='2022-10-20',
        publishs_id=2  ## 如果用的是属性名称_id,那么值为关联记录的id值
    )
    return  HttpResponse('ok')

## 多对多的关系添加
    ## 第一种写法
    book_boj = models.Book.objects.get(title='水浒传')
    author01 = models.Author.objects.get(id=1)
    author02 = models.Author.objects.get(id=2)
    book_boj.authors.add(author01,author02)
    ## 第二种写法,你只要的id值了可以直接写id
    book_boj = models.Book.objects.get(title='水浒传')
    book_boj.authors.add(1,2)
    return  HttpResponse('ok')

删除

复制代码
# 一对一删除
def query(request):   
    ## 第一种方法
    models.Author.objects.get(id=1).delete()
    ## 第二种方法  外键关联到这条作者记录的都会被删除掉(级联模式下)
    models.AuthDetail.objects.get(id=2).delete()
    return  HttpResponse('查询成功')
     ## 一对多的删除,可以把多的关系那一方比喻成大腿,大腿没了那所有的就都没了,单个没了不会影响到大腿的那一方
    models.Book.objects.get(id=2).delete()  
    models.Publish.objects.get(id=2).delete()
    return  HttpResponse('ok')

# 一对多删除
def query(request):   
    ## 一对多的删除,可以把多的关系那一方比喻成大腿,大腿没了那所有的就都没了,单个没了不会影响到大腿的那一方
    ## 删除一的那一方
    models.Book.objects.get(id=2).delete()
    ## 删除多的那一方
    models.Publish.objects.get(id=2).delete()
    return  HttpResponse('ok')
# 多对多删除
def query(request):   
    book_obj = models.Book.objects.get(id=14)
    ## clear清空所有
    book_obj.authors.clear()
    ## remove 只删除单个 
    book_obj.authors.remove(3)  ## 删除第三章表的book_id=14 并且作者id=3的那条记录
    return  HttpResponse('ok')

查询-基于对象的跨表查询

复制代码
## 一对一的
## 正向查询,关系属性在哪个表里面,通过这个表的数据去查询另外一张表的数据,就是正向查询
# 查询张三这个作者的手机号,先查出这个张三这个作者通过外键找到作者详情表然后取出手机号
def query(request): 
  obj = models.Author.objects.get(name='张三')
  print(obj.au.telephone)  ## 正向查询靠属性
  return  HttpResponse('查询成功')

## 一对多的
## 正向查询,这里的书籍和出版社是1:n的关系,通过外键publishs关联
def query(request): 
  obj = models.Book.objects.get(title='佛经1')
  print(obj.publishs.name)
  return  HttpResponse('查询成功')

## 反向查询
def query(request): 
    obj = models.Publish.objects.get(name='清华出版社')
    books = obj.book_set.filter() ## 反向查询在一对多的关系是,使用  表名小写_set
    for book in books:
        print(book.title)
    return  HttpResponse('查询成功')

## 多对多的
# 正向查询
def query(request): 
    obj = models.Book.objects.filter(title='佛经2').first()
    objs = obj.authors.all()  ## #类似objects控制器
    for obj in objs:
        print(obj.name)
    return  HttpResponse('查询成功')
# 反向查询
## 查询一下张三写了哪些书
def query(request):
    obj = models.Author.objects.get(name='张三')
    objs = obj.book_set.all()
    for i in objs:
        print(i.title)

基于双下划线的跨表查询

复制代码
## 正向查询靠属性, 反向查询靠表名小写
def query(request):
    ## 一对一的
    ## 正向查询,查询一下志邦这个作者的手机号
    ret = models.Author.objects.filter(name='志邦').values('au__telephone')
    print(ret)
    ## <QuerySet [{'au__telephone': 122}]>
    
    ## 反向查询
    ret = models.AuthDetail.objects.filter(author__name='志邦').values('telephone')
    print(ret)
    return  HttpResponse('查询成功')

def query(request):  
    ## 正向查询  
    ret = models.Book.objects.filter(title='三体').values('authors__name')
    print(ret)
    ## 反向查询
    ret = models.Author.objects.filter(book__title='三体').values('name')
    print(ret)
    return  HttpResponse('查询成功')

聚合查询

复制代码
def query(request):
    ## 查询所有书籍的平均价格    
    ret = models.Book.objects.all().aggregate(Avg('price'))
    print(ret)
    return  HttpResponse('查询成功')

想了解更多的知识点的可以访问我的个人博客:https://xingzhibang.top/

相关推荐
AI_56789 小时前
基于职业发展的Python与Java深度对比分析
java·人工智能·python·信息可视化
寻星探路9 小时前
【Python 全栈测开之路】Python 进阶:库的使用与第三方生态(标准库+Pip+实战)
java·开发语言·c++·python·ai·c#·pip
子夜江寒11 小时前
基于 OpenCV 的图像形态学与边缘检测
python·opencv·计算机视觉
少林码僧17 小时前
2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法
人工智能·python·算法·机器学习·ai·数据挖掘
智航GIS18 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
jarreyer18 小时前
摄像头相关记录
python
宝贝儿好18 小时前
【强化学习】第六章:无模型控制:在轨MC控制、在轨时序差分学习(Sarsa)、离轨学习(Q-learning)
人工智能·python·深度学习·学习·机器学习·机器人
大、男人18 小时前
python之asynccontextmanager学习
开发语言·python·学习
默默前行的虫虫19 小时前
nicegui文件上传归纳
python