前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Django】 开发:数据库操作和后台管理

【Django】 开发:数据库操作和后台管理

作者头像
杨丝儿
发布2022-02-24 09:01:54
4.1K0
发布2022-02-24 09:01:54
举报
文章被收录于专栏:杨丝儿的小站

查询数据

  • 数据库的查询需要使用管理器对象进行
  • 通过 MyModel.objects 管理器方法调用查询接口

方法

说明

all()

查询全部记录,返回QuerySet查询对象

get()

查询符合条件的单一记录

filter()

查询符合条件的多条记录

exclude()

查询符合条件之外的全部记录

1. all () 方法

  • 方法: all ()
  • 用法: MyModel.objects.all ()
  • 作用:查询 MyModel 实体中所有的数据
  • 等同于

select * from tabel

  • 返回值: QuerySet 容器对象,内部存放 MyModel 实例
  • 示例:
代码语言:javascript
复制
from bookstore.models import Book
books = Book.objects.all()
for book in books:
    print("书名", book.title, '出版社:', book.pub)

2. 在模型类中定义 def __str__(self): 方法可以自定义默认的字符串

代码语言:javascript
复制
class Book(models.Model):
    title = ...
    def __str__(self):
        return "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)

3.查询返回指定列 (字典表示)

  • 方法: values (‘列 1’, ‘列 2’)
  • 用法: MyModel.objects.values (…)
  • 作用:查询部分列的数据并返回

select 列 1, 列 2 from xxx

  • 返回值: QuerySet

返回查询结果容器,容器内存字典,每个字典代表一条数据,

格式为: {‘列 1’: 值 1, ‘列 2’: 值 2}

  • 示例:
代码语言:javascript
复制
from bookstore.models import Book
books = Book.objects.values("title", "pub")
for book in books:
    print("书名", book["title"], '出版社:', book['pub'])
    print("book=", book)

4.查询返回指定列(元组表示)

  • 方法:values_list (‘列 1’,‘列 2’)
  • 用法:MyModel.objects.values_list (…)
  • 作用:

返回元组形式的查询结果

  • 返回值: QuerySet 容器对象,内部存放 元组

会将查询出来的数据封装到元组中,再封装到查询集合 QuerySet 中

  • 示例:
代码语言:javascript
复制
from bookstore.models import Book
books = Book.objects.values_list("title", "pub")
for book in books:
    print("书名", book[0], '出版社:', book[1])
    print("book=", book)  # ('Python', '清华大学出版社')...

5.排序查询

  • 方法:order_by
  • 用法:MyModel.objects.order_by (’- 列’,‘列’)
  • 作用:

与 all () 方法不同,它会用 SQL 语句的 ORDER BY 子句对查询结果进行根据某个字段选择性的进行排序

  • 说明:

默认是按照升序排序,降序排序则需要在列前增加’-' 表示

  • 示例:
代码语言:javascript
复制
from bookstore.models import Book
books = Book.objects.order_by("price")
for book in books:
print("书名:", book.title, '定价:', book.price)

6.条件查询 - filte

  • 方法: filter (条件)
  • 语法:
代码语言:javascript
复制
MyModel.objects.filter(属性1=值1, 属性2=值2)
  • 返回值:

QuerySet 容器对象,内部存放 MyModel 实例

  • 说明:

当多个属性在一起时为 "与" 关系,即当 Books.objects.filter(price=20, pub="清华大学出版社") 返回定价为 20 且 出版社为 "清华大学出版社" 的全部图书

  • 示例:
代码语言:javascript
复制
# 查询书中出版社为"清华大学出版社"的图书
from bookstore.models import Book
books = Book.objects.filter(pub="清华大学出版社")
for book in books:
        print("书名:", book.title)
    
# 查询Author实体中name为王老师并且age是28岁的
authors=Author.objects.filter(name='王老师',age=28)

7.条件查询 - exclude

  • 方法: exclude (条件)
  • 语法:

MyModel.objects.exclude (条件)

  • 作用:

返回不包含此 条件 的 全部的数据集

  • 示例:

查询 清华大学出版社,定价等于50 以外的全部图书

代码语言:javascript
复制
books = Book.objects.exclude(pub="清华大学出版社", price=50)
for book in books:
    print(book)

8.条件查询 - get

  • 方法: get (条件)
  • 语法:

MyModel.objects.get (条件)

  • 作用:

返回满足条件的唯一一条数据

  • 说明:

该方法只能返回一条数据

查询结果多余一条数据则抛出,Model.MultipleObjectsReturned 异常

查询结果如果没有数据则抛出 Model.DoesNotExist 异常

  • 示例:
代码语言:javascript
复制
from bookstore.models import Book
book = Book.objects.get(id=1)
print(book.title)

查询谓词

  • 每一个查询谓词是一个独立的查询功能

1.__exact : 等值匹配

代码语言:javascript
复制
Author.objects.filter(id__exact=1)
# 等同于select * from author where id = 1

2.__contains : 包含指定值

代码语言:javascript
复制
Author.objects.filter(name__contains='w')
# 等同于 select * from author where name like '%w%'

3.__startswith : 以 XXX 开始

4.__endswith : 以 XXX 结束

5.__gt : 大于指定值

代码语言:javascript
复制
Author.objects.filer(age__gt=50)
# 等同于 select * from author where age > 50

6.__gte : 大于等于

7.__lt : 小于

8.__lte : 小于等于

9.__in : 查找数据是否在指定范围内

  • 示例
代码语言:javascript
复制
Author.objects.filter(country__in=['中国','日本','韩国'])
# 等同于 select * from author where country in ('中国','日本','韩国')

10.__range: 查找数据是否在指定的区间范围内

代码语言:javascript
复制
# 查找年龄在某一区间内的所有作者
Author.objects.filter(age__range=(35,50))
# 等同于 SELECT ... WHERE Author BETWEEN 35 and 50;

11.详细内容参见: https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups

  • 示例
代码语言:javascript
复制
MyModel.objects.filter(id__gt=4)
# 等同于 SELECT ... WHERE id > 4;

修改数据

1.修改单个实体的某些字段值的步骤:

  • 通过 get () 得到要修改的实体对象

  • 通过 对象。属性 的方式修改数据

保存

  • 通过 对象.save () 保存数据

如:

代码语言:javascript
复制
from bookstore.models import Book
abook = Book.objects.get(id=10)
abook.market_price = "10.5"
abook.save()

2.通过 QuerySet 批量修改 对应的全部字段

直接调用 QuerySet 的 update (属性 = 值) 实现批量修改

返回值:更新数据的数量

如:

代码语言:javascript
复制
# 将id大于3的所有图书价格定为0元
books = Book.objects.filter(id__gt=3)
books.update(price=0)
# 将所有书的零售价定为100元
books = Book.objects.all()
books.update(market_price=100)

删除数据

  • 删除记录是指删除数据库中的一条或多条记录
  • 删除单个MyModel对象或删除一个查询结果集(QuerySet)中的全部对象都是调用 delete()方法

删除单个对象

步骤

  1. 查找查询结果对应的一个数据对象
  2. 调用这个数据对象的 delete () 方法实现删除

示例:

代码语言:javascript
复制
try:
    auth = Author.objects.get(id=1)
    auth.delete()
except:
    print(删除失败)

删除查询结果集

步骤

  1. 查找查询结果集中满足条件的全部 QuerySet 查询集合对象
  2. 调用查询集合对象的 delete () 方法实现删除

示例:

代码语言:javascript
复制
# 删除全部作者中,年龄大于65的全部信息
auths = Author.objects.filter(age__gt=65)
auths.delete()

聚合查询

  • 聚合查询是指对一个数据表中的一个字段的数据进行部分或全部进行统计查询,查bookstore_book数据表中的全部书的平均价格,查询所有书的总个数等,都要使用聚合查询

不带分组聚合

  • 不带分组的聚合查询是指导将全部数据进行集中统计查询
  • 聚合函数【需要导入】:

导入方法: from django.db.models import *

聚合函数:

Sum, Avg, Count, Max, Min

  • 语法:

MyModel.objects.aggregate (结果变量名 = 聚合函数 (‘列’))

  • 返回结果:

由 结果变量名和值组成的字典

格式为:

`{“结果变量名”: 值}

  • 示例:
代码语言:javascript
复制
    # 得到所有书的平均价格
    from bookstore.models import Book
    from django.db.models import Avg
    result = Book.objects.aggregate(myAvg=Avg('price'))
    print("平均价格是:", result['myAvg'])
    print("result=", result)  # {"myAvg": 58.2}
    
    # 得到数据表里有多少本书
    from django.db.models import Count
    result = Book.objects.aggregate(mycnt=Count('title'))
    print("数据记录总个数是:", result['mycnt'])
print("result=", result)  # {"mycnt": 10}

分组聚合

  • 分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值 (也可以是平均值或总和),即为查询集的每一项生成聚合。
  • 语法:

QuerySet.annotate (结果变量名 = 聚合函数 (‘列’))

  • 用法步骤:

通过先用查询结果 MyModel.objects.values 查找查询要分组聚合的列

MyModel.objects.values (‘列 1’, ‘列 2’)

如:

代码语言:javascript
复制
    pub_set = Book.objects.values('pub')
print(pub_set)  # <QuerySet [{'pub': '清华大学出版社'}, {'pub': '清华大学出版社'}, {'pub_hou {'pub': '机械工业出版社'}, {'pub': '清华大学出版社'}]>

通过返回结果的 QuerySet.annotate 方法分组聚合得到分组结果

QuerySet.annotate (名 = 聚合函数 (‘列’))

返回 QuerySet 结果集,内部存储结果的字典

如:

代码语言:javascript
复制
pub_count_set = pub_set.annotate(myCount=Count('pub'))
print(pub_count_set)  # <QuerySet [{'pub': '清华大学出版社', 'myCount': 7}, {'pub': '机械工业出版社', 'myCount': 3}]>
  • 示例:

得到哪儿个出版社共出版多少本书

代码语言:javascript
复制
def test_annotate(request):
   from django.db.models import Count
   from . import models
    
    # 得到所有出版社的查询集合QuerySet
    pub_set = models.Book.objects.values('pub')
    # 根据出版社查询分组,出版社和Count的分组聚合查询集合
    pub_count_set = pub_set.annotate(myCount=Count('pub'))  # 返回查询集合
    for item in pub_count_set:
        print("出版社:", item['pub'], "图书有:", item['myCount'])
    return HttpResponse('请查看服务器端控制台获取结果')

F对象

  • 一个F对象代表数据库中某条记录的字段的信息
  • 作用:

通常是对数据库中的字段值在不获取的情况下进行操作

用于类属性 (字段) 之间的比较。

  • 用法

F 对象在数据包 django.db.models 中,使用时需要先导入

from django.db.models import F

  • 语法:
代码语言:javascript
复制
from django.db.models import F
F('列名')  
  • 说明:

一个 F () 对象代表了一个 model 的字段的值

F 对象通常是对数据库中的字段值在不加载到内存中的情况下直接在数据库服务器端进行操作

  • 示例 1

更新 Book 实例中所有的零售价涨 10 元

代码语言:javascript
复制
Book.objects.all().update(market_price=F('market_price')+10)
'UPDATE `bookstore_book` SET `market_price` = (`bookstore_book`.`market_price` + 10) 
# 以上做法好于如下代码
books = Book.objects.all()
for book in books:
    book.market_price=book.marget_price+10
    book.save()
  • 示例 2

对数据库中两个字段的值进行比较,列出哪儿些书的零售价高于定价?

代码语言:javascript
复制
from django.db.models import F
from bookstore.models import Book
books = Book.objects.filter(market_price__gt=F('price'))
'SELECT * FROM `bookstore_book` WHERE `bookstore_book`.`market_price` > (`bookstore_book`.`price`)
for book in books:
    print(book.title, '定价:', book.price, '现价:', book.market_price)

Q对象

  • 当在获取查询结果集 使用复杂的逻辑或 | 、 逻辑非 ~ 等操作时可以借助于 Q 对象进行操作
  • 如:想找出定价低于 20 元 或 清华大学出版社的全部书,可以写成
代码语言:javascript
复制
Book.objects.filter(Q(price__lt=20)|Q(pub="清华大学出版社"))
  • Q 对象在 数据包 django.db.models 中。需要先导入再使用

from django.db.models import Q

  • 作用

在条件中用来实现除 and (&) 以外的 or (|) 或 not (~) 操作

  • 运算符:

& 与操作

| 或操作

〜 非操作

  • 语法
代码语言:javascript
复制
from django.db.models import Q
Q(条件1)|Q(条件2)  # 条件1成立或条件2成立
Q(条件1)&Q(条件2)  # 条件1和条件2同时成立
Q(条件1)&~Q(条件2)  # 条件1成立且条件2不成立
...
  • 示例
代码语言:javascript
复制
from django.db.models import Q
# 查找清华大学出版社的书或价格低于50的书
Book.objects.filter(Q(market_price__lt=50) | Q(pub_house='清华大学出版社'))
# 查找不是机械工业出版社的书且价格低于50的书
Book.objects.filter(Q(market_price__lt=50) & ~Q(pub_house='机械工业出版社'))

原生的数据库操作方法

  • 使用MyModel.objects.raw()进行 数据库查询操作查询
    • 在django中,可以使用模型管理器的raw方法来执行select语句进行数据查询
    1. 语法:
      • MyModel.objects.raw(sql语句,[拼接参数])
    2. 用法
      • MyModel.objects.raw('sql语句', [拼接参数])
    3. 返回值:
      • RawQuerySet 集合对象 【只支持基础操作,比如循环】
    4. 示例
代码语言:javascript
复制
books = Book.objects.raw('select * from bookstore_book')
for book in books:
    print(book)

#sql注入问题
s1 = Book.objects.raw('select * from bookstore_book where id=%s'%('1 or 1=1'))

s2 = Book.objects.raw('select * from bookstore_book where id=%s',['1 or 1=1'])
    
  • 使用django中的游标cursor对数据库进行 增删改查 操作

在 Django 中跨过模型类直接操作数据库

使用步骤:

导入 cursor 所在的包

Django 中的游标 cursor 定义在 django.db.connection 包中,使用前需要先导入

如:

from django.db import connection

用创建 cursor 类的构造函数创建 cursor 对象,再使用 cursor 对象,为保证在出现异常时能释放 cursor 资源,通常使用 with 语句进行创建操作

如:

代码语言:javascript
复制
from django.db import connection
with connection.cursor() as cur:
    cur.execute('执行SQL语句', '拼接参数')

示例

代码语言:javascript
复制
   # 用SQL语句将id 为 10的 书的出版社改为 "XXX出版社"
   from django.db import connection
   with connection.cursor() as cur: 
cur.execute('update bookstore_book set pub_house="XXX出版社" where id=10;')
   
   with connection.cursor() as cur:
       # 删除 id为1的一条记录
       cur.execute('delete from bookstore_book where id=10;')

admin 后台数据库管理

django 提供了比较完善的后台管理数据库的接口,可供开发过程中调用和测试使用

django 会搜集所有已注册的模型类,为这些模型类提拱数据管理界面,供开发者使用

使用步骤:

  1. 建后台管理帐号:
  • 后台管理–创建管理员帐号

$ python3 manage.py createsuperuse

根据提示完成注册,参考如下:

代码语言:javascript
复制
$ python3 manage.py createsuperuse
Username (leave blank to use 'tarena'): tarena  # 此处输入用户名
Email address: laowei@tedu.cn  # 此处输入邮箱
Password: # 此处输入密码(密码要复杂些,否则会提示密码太简单)
Password (again): # 再次输入重复密码
Superuser created successfully.
$ 

2.用注册的帐号登陆后台管理界面

代码语言:javascript
复制
后台管理的登录地址:

http://127.0.0.1:8000/admin/

注册自定义模型类

若要自己定义的模型类也能在 后台管理界中显示和管理,需要将自己的类注册到后台管理界面

添加自己定义模型类的后台管理数据表的,需要用 方法进行注册

  • 配置步骤如下:

1.在应用 app 中的 admin.py 中导入注册要管理的模型 models 类,如:

代码语言:javascript
复制
from .models import Book

2.调用 admin.site.register 方法进行注册,如:

代码语言:javascript
复制
from django.contrib import admin
admin.site.register(自定义模型类)
  • 如:在 bookstore/admin.py 添加如下代码对 Book 类进行管理
  • 示例:
代码语言:javascript
复制
# file: bookstore/admin.py
from django.contrib import admin
# Register your models here.

from . import models
...
admin.site.register(models.Book)  # 将Book类注册为可管理页面

修改自定义模型类的展现样式

在admin后台管理数据库中对自定义的数据记录都展示为 类型的记录,不便于阅读和判断

在用户自定义的模型类中可以重写 方法解决显示问题,如:

  • 在 自定义模型类中重写 str(self) 方法返回显示文字内容:
代码语言:javascript
复制
class Book(models.Model):
    ...
    def __str__(self):
        return "书名" + self.title

模型管理器类

  • 作用

为后台管理界面添加便于操作的新功能。

  • 说明:

后台管理器类须继承自 django.contrib.admin 里的 ModelAdmin 类

  • 模型管理器的使用方法:

在 <应用app>/admin.py 里定义模型管理器类

代码语言:javascript
复制
class XXXXManager(admin.ModelAdmin):
    ......

绑定注册模型管理器和模型类

代码语言:javascript
复制
from django.contrib import admin
from .models import *
admin.site.register(YYYY, XXXXManager) # 绑定 YYYY 模型类与 管理器类 XXXXManage

示例:

代码语言:javascript
复制
# file : bookstore/admin.py
from django.contrib import admin
from .models import Book

class BookManager(admin.ModelAdmin):
    list_display = ['id', 'title', 'price', 'market_price']
    admin.site.register(Book, BookManager)

进入 http://127.0.0.1:8000/admin/bookstore/book/ 查看显示方式和以前有所不同

  • 模型管理器类 ModelAdmin 中实现的高级管理功能
  1. list_display 去控制哪些字段会显示在 Admin 的修改列表页面中。
  2. list_display_links 可以控制 list_display 中的字段是否应该链接到对象的 “更改” 页面。
  3. list_filter 设置激活 Admin 修改列表页面右侧栏中的过滤器
  4. search_fields 设置启用 Admin 更改列表页面上的搜索框。
  5. list_editable 设置为模型上的字段名称列表,这将允许在更改列表页面上进行编辑。
  6. 其它参见 https://docs.djangoproject.com/en/2.2/ref/contrib/admin/

再谈Meta类

通过Meta内嵌类 定义模型类的属性

模型类可以通过定义内部类class Meta 来重新定义当前模型类和数据表的一些属性信息

用法格式如下:

代码语言:javascript
复制
class Book(models.Model):
    title = CharField(....)
    class Meta:
        1. db_table = '数据表名'
            - 该模型所用的数据表的名称。(设置完成后需要立马更新同步数据库)
        2. verbose_name = '单数名'
            - 给模型对象的一个易于理解的名称(单数),用于显示在/admin管理界面中
        3. verbose_name_plural = '复数名'
            - 该对象复数形式的名称(复数),用于显示在/admin管理界面中

数据表关联关系映射

  • 常用的表关联方式有三种:
    1. 一对一映射
      • 如: 一个身份证对应一个人
    2. 一对多映射
      • 如: 一个班级可以有多个学生
    3. 多对多映射
      • 如: 一个学生可以报多个课程,一个课程可以有多个学生学习

一对一映射

  • 一对一是表示现实事物间存在的一对一的对应关系。
  • 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等

语法

代码语言:javascript
复制
class A(model.Model):
    ...
class B(model.Model):
    属性 = models.OneToOneField(A, on_delete=xxx)

外键类字段选项

  • 特殊字段参数【必须项】:
    • on_delete
      1. models.CASCADE 级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
      2. models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICT]
      3. models.SET_NULL 设置ForeignKey null;需要指定null=True
      4. models.SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
      5. … 其它参请参考文档 https://docs.djangoproject.com/en/2.2/ref/models/fields/#foreignkey
  • 其余常用的字段选项【非必须项】;如:
    1. null
    2. unique 等

用法示例

1.创建作家和作家妻子类

代码语言:javascript
复制
# file : xxxxxxxx/models.py
from django.db import models

class Author(models.Model):
    '''作家模型类'''
    name = models.CharField('作家', max_length=50)

class Wife(models.Model):
    '''作家妻子模型类'''
    name = models.CharField("妻子", max_length=50)
    author = models.OneToOneField(Author, on_delete=models.CASCADE)  # 增加一对一属性 

2.创建一对一的数据记录

代码语言:javascript
复制
from .models import *
author1 = Author.objects.create(name='王老师')
wife1 = Wife.objects.create(name='王夫人', author=author1)  # 关联王老师
author2 = Author.objects.create(name='小泽老师')  # 一对一可以没有数据对应的数据 

3.数据查询

正向查询

直接通过关联属性查询即可

代码语言:javascript
复制
# 通过 wife 找 autho
from .models import Wife
wife = Wife.objects.get(name='王夫人')
print(wife.name, '的老公是', wife.author.name)

反向查询

通过反向关联属性查询

反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.wife

当反向引用不存在时,则会触发异常

代码语言:javascript
复制
# 通过 author.wife 关联属性 找 wife,如果没有对应的wife则触发异常
author1 = Author.objects.get(name='王老师')
print(author1.name, '的妻子是', author1.wife.name)
author2 = Author.objects.get(name='小泽老师')
try:
    print(author2.name, '的妻子是', author2.wife.name)
except:
    print(author2.name, '还没有妻子')

一对多映射

  • 一对多是表示现实事物间存在的一对多的对应关系。
  • 如:一个学校有多个班级,一个班级有多个学生, 一本图书只能属于一个出版社,一个出版社允许出版多本图书

1.语法

  • 当一个 A 类对象可以关联多个 B 类对象时
代码语言:javascript
复制
class A(model.Model)    ...

class B(model.Model):
    属性 = models.ForeignKey("一"的模型类, on_delete=xx)

2.用法示例

  • 有二个出版社对应五本书的情况.

清华大学出版社 有书

C++

Java

Python

北京大学出版社 有书

西游记

水浒

3.创建模型类

代码语言:javascript
复制
# file: otm/models.py
from django.db import models

class Publisher(models.Model):
    '''出版社【一】'''
    name = models.CharField('名称', max_length=50, unique=True)

class Book(models.Model):
    '''书【多】'''
    title = models.CharField('书名', max_length=50)
    publisher = ForeignKey(Publisher, on_delete=models.CASCADE)

4.创建数据

代码语言:javascript
复制
#先创建 '一' ,再创建 '多'
from .models import *
pub1 = Publisher.objects.create(name='清华大学出版社')
Book.objects.create(title='C++', publisher=pub1)
Book.objects.create(title='Java', publisher_id=1)

#高级创建 - 利用 反向属性
pub2 = Publisher.objects.create(name='北京大学出版社')
pub2.book_set.create(title='西游记')

5.数据查询

通过 Book 查询 Publisher【正向】

代码语言:javascript
复制
通过 publisher 属性查询即可
book.publishe
 
abook = Book.objects.get(id=1)
print(abook.title, '的出版社是:', abook.publisher.name)

通过 Publisher 查询 对应的所有的 Book 【反向】

代码语言:javascript
复制
Django会在Publisher中增加一个属性来表示对对应的Book们的查询引用
属性:book_set  等价于 objects

# 通过出版社查询对应的书
pub1 = Publisher.objects.get(name='清华大学出版社')
books = pub1.book_set.all()  # 通过book_set 获取pub1对应的多个Book数据对象
#books = Book.objects.filter(publisher=pub1)  # 也可以采用此方式获取
print("清华大学出版社的书有:")
for book in books:
   print(book.title)

多对多映射

  • 多对多表达对象之间多对多复杂关系,如: 每个人都有不同的学校(小学,初中,高中,…),每个学校都有不同的学生…

1.语法

在关联的两个类中的任意一个类中,增加:

代码语言:javascript
复制
属性 = models.ManyToManyField(MyModel)

2.用法示例

  • 一个作者可以出版多本图书
  • 一本图书可以被多名作者同时编写
代码语言:javascript
复制
class Author(models.Model):
    ...

class Book(models.Model):
    ...
    authors = models.ManyToManyField(Author)

3.创建模型类

代码语言:javascript
复制
class Author(models.Model):
    '''作家模型类'''
    name = models.CharField('作家', max_length=50)
    def __str__(self):
        return self.name
    
class Book(models.Model):
    '''书模型类'''
    title = models.CharField('书名', max_length=50)
    authors = models.ManyToManyField(Author)
    def __str__(self):
           return self.title 

4.创建数据

代码语言:javascript
复制
方案1 先创建 author 再关联 book
    author1 = Author.objects.create(name='吕老师')
    author2 = Author.objects.create(name='王老师')
    # 吕老师和王老师同时写了一本Python
    book11 = author1.book_set.create(title="Python")
    author2.book_set.add(book11) 
    
方案2 先创建 book 再关联 autho
    book = Book.objects.create(title='python1')
    #郭小闹和吕老师都参与了 python1 的 创作
    author3 = book.authors.create(name='guoxiaonao')
    book.authors.add(author1)

5.数据查询

通过 Book 查询对应的所有的 Author【正向】

代码语言:javascript
复制
book.authors.all() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息

通过 Author 查询对应的所有的 Book【反向】

Django 会生成一个反向属性 book_set 用于表示对对应的 book 的查询对象相关操作

代码语言:javascript
复制
author.book_set.all()
author.book_set.filter()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 查询数据
    • 1. all () 方法
      • 2. 在模型类中定义 def __str__(self): 方法可以自定义默认的字符串
        • 3.查询返回指定列 (字典表示)
          • 4.查询返回指定列(元组表示)
            • 6.条件查询 - filte
              • 7.条件查询 - exclude
                • 8.条件查询 - get
                • 查询谓词
                • 修改数据
                  • 1.修改单个实体的某些字段值的步骤:
                    • 2.通过 QuerySet 批量修改 对应的全部字段
                    • 删除数据
                    • 聚合查询
                    • F对象
                    • Q对象
                    • 原生的数据库操作方法
                    • admin 后台数据库管理
                      • 注册自定义模型类
                        • 修改自定义模型类的展现样式
                          • 模型管理器类
                            • 再谈Meta类
                            • 数据表关联关系映射
                              • 一对一映射
                                • 一对多映射
                                  • 多对多映射
                                  相关产品与服务
                                  数据库
                                  云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档