Django 学习日记 - Databse Operation -setp9

1 ORM常用操作

1.1 概念

Django 学习日记 - Databse Operation -setp9_第1张图片
ORM机制

对象关系映射(英语:Object Relational Mapping,简称ORM),用于实现面向对象编程语言里不同类型系统的数据之间的转换。换句话说,就是用面向对象的方式去操作数据库的创建表,增加、修改、删除、查询等操作。

1.2 查看ORM生成的sql语句。

1.2.1 使用QuerySet中的query属性

user_list = User.objects.all()
print(user_list.query)

1.2.2 使用Logging日志查看

前面有提及,此处略

1.3 ORM优缺点

1.3.1 优点

  1. ORM使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
  2. 可以避免一些新手程序猿写sql语句带来的性能效率和安全问题:select * from table效率低,避免sql注入风险

1.3.2 缺点

  1. 性能有所牺牲,不过现在的各种ORM框架都在尝试使用各种方法来减轻这个问题(LazyLoad,Cache),效果还是很显著的。
  2. 对于个别复杂查询,ORM仍然力不从心。为解决这个问题,ORM框架一般也提供了直接写原生sql的方式。

1.4 ORM 机制下面的增删查改操作

本次所有的实验测试都在manage.py的shell模式下面进行操作,建议安装IPython提高交互

Django 学习日记 - Databse Operation -setp9_第2张图片
进入Shell编辑界面

D:\virtualenv\env_py35_django\Scripts>activate
(env_py35_django) D:\virtualenv\env_py35_django\Scripts>cd D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django

(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>python manage.py shell
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

安装IPython的编辑器,提供更为强大的编辑和交互功能。


Django 学习日记 - Databse Operation -setp9_第3张图片
安装IPython后的编辑界面
(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>pip install ipython
Successfully installed appdirs-1.4.0 colorama-0.3.7 decorator-4.0.11 ipython-5.2.2 ipython-genutils-0.1.0 packaging-16.8 pickleshare-0.7.4 prompt-toolkit-1.0.13 pygments-2.2.0 pyparsing-2.1.10 setuptools-34.1.1 simplegeneric-0.8.1 traitlets-4.3.1 wcwidth-0.1.7 win-unicode-console-0.5

(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>python manage.py shell
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 5.2.2 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]:

注意:每次退出shell模式都要重新导入 from hello.models import *

1.4.1 增

  1. 插入简单数据:
In [1]: from hello.models import *
In [2]: Author.objects.create(name='蓝盾')
(0.000) BEGIN; args=None
(0.033) INSERT INTO "hello_author" ("name") VALUES ('蓝盾'); args=['蓝盾']
Out[2]: 
Django 学习日记 - Databse Operation -setp9_第4张图片
create的方法插入简单数据
  1. 插入一对多关系数据:使用create方法,外键的字段输入的是对应外键的id值
In [4]: AuthorDetail.objects.create(sex=False,email='[email protected]',address='www.landun.com',birthday='2017-1-19',author_id=4)
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_authordetail" ("sex", "email", "address", "birthday", "author_id") VALUES (0, '[email protected]', 'www.landun.com', '2017-01-19', 4); args=[False, '[email protected]', 'www.landun.com', '2017-01-19', 4]
Out[4]: 
Django 学习日记 - Databse Operation -setp9_第5张图片
create的方法插入一对多关系数据
  1. 通过对象的方法插入数据:实例化对象,给对象加入属性,通过save方法保存
In [5]: pub = Publisher()
   ...: pub.name = "电子工业出版社"
   ...: pub.address = "广东广州"
   ...: pub.city = "广州"
   ...: pub.state_province = "广州"
   ...: pub.city = "广东"
   ...: pub.country = "中国"
   ...: pub.website = "http://www.baidu.com"
   ...: pub.save()
   ...:
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_publisher" ("name", "address", "city", "state_province", "country", "website") VALUES ('电子工业出版社', '广东广州', '广东', '广州', '中国', 'http://www.baidu.com'); args=['电子工业出版社', '广东广州', '广东', '广州', '中国', 'http://www.baidu.com']
Django 学习日记 - Databse Operation -setp9_第6张图片
通过对象的方法插入数据
  1. 通过对象的方法插入多对多的数据:通过get方法获取两个对象的实例,然后再用add方法来关联他们之间的关系
In [6]: Book.objects.create(title='Pytho实战',publisher=pub,publication_date='2015-5-6')
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_book" ("title", "publisher_id", "publication_date", "price") VALUES ('Pytho实战', 8, '2015-05-06', '10.00'); args=['Pytho实战', 8, '2015-05-06', '10.00']
Out[6]: 
In [7]: book = Book.objects.get(id=1)
(0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
In [8]: author = Author.objects.get(id=1)
(0.000) SELECT "hello_author"."id", "hello_author"."name" FROM "hello_author" WHERE "hello_author"."id" = 1; args=(1,)
In [9]: book.authors.add(author)
(0.000) BEGIN; args=None
(0.000) SELECT "hello_book_authors"."author_id" FROM "hello_book_authors" WHERE ("hello_book_authors"."book_id" = 1 AND "hello_book_authors"."author_id" IN (1)); args=(1, 1)
Django 学习日记 - Databse Operation -setp9_第7张图片
通过对象的方法插入多对多的数据

1.4.2 删【级联删除】

使用filter方法过滤在用delete删除,注意所有的删除都是级联删除

In [10]: Book.objects.filter(id=13).delete()
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 13; args=(13,)
(0.000) BEGIN; args=None
(0.001) DELETE FROM "hello_book_authors" WHERE "hello_book_authors"."book_id" IN (13); args=(13,)
(0.048) DELETE FROM "hello_book" WHERE "hello_book"."id" IN (13); args=(13,)
Out[10]: (1, {'hello.Book': 1, 'hello.Book_authors': 0})
Django 学习日记 - Databse Operation -setp9_第8张图片
delete的方法删除

1.4.3 查【惰性查询】

  • 惰性查询:直到使用的时候才会对数据库进行查询
  • shell下面是非惰性的,py文件下面都是惰性查询
  • 查询使用filter得到的是QuerySet对象,使用get芳芳得到的是一个models对象
In [11]: Book.objects.filter(id=1)
Out[11]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1 LIMIT 21; args=(1,)
[]
In [13]: type(Book.objects.filter(id=1))
Out[13]: django.db.models.query.QuerySet
In [12]: Book.objects.get(id=1)
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
Out[12]: 
In [14]: type(Book.objects.get(id=1))
(0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
Out[14]: hello.models.Book
Django 学习日记 - Databse Operation -setp9_第9张图片
使用filter和get方法进行查询

1.4.4 改

  1. save的方法简单修改表数据(get和save结合)
In [14]: author = Author.objects.get(id=4)
(0.001) SELECT "hello_author"."id", "hello_author"."name" FROM "hello_author" WHERE "hello_author"."id" = 4; args=(4,)
In [15]: print(author.name)
蓝盾
In [16]: author.name = "蓝视"
In [17]: author.save()
(0.000) BEGIN; args=None
(0.126) UPDATE "hello_author" SET "name" = '蓝视' WHERE "hello_author"."id" = 4; args=('蓝视', 4)
In [18]: print(author.name)
蓝视
Django 学习日记 - Databse Operation -setp9_第10张图片
save的方法简单修改表数据
  1. save的方法修改关联表数据(get和save结合)
In [19]: authordetail =AuthorDetail.objects.get(author=author)
(0.001) SELECT "hello_authordetail"."id", "hello_authordetail"."sex", "hello_authordetail"."email", "hello_authordetail"."address", "hello_authordetail"."birthday", "hello_authordetail"."author_id" FROM "hello_authordetail" WHERE "hello_authordetail"."author_id" = 4; args=(4,)
In [20]: print(authordetail.sex)
False
In [21]: authordetail.sex = True
In [22]: print(authordetail.sex)
True
In [23]: authordetail.save()
(0.000) BEGIN; args=None
(0.001) UPDATE "hello_authordetail" SET "sex" = 1, "email" = '[email protected]', "address" = 'www.landun.com', "birthday" = '2017-01-19', "author_id" = 4 WHERE "hello_authordetail"."id" = 5; args=(True, '[email protected]', 'www.landun.com', '2017-01-19', 4, 5)
>>>
Django 学习日记 - Databse Operation -setp9_第11张图片
save的方法修改关联表的数据
  1. upadte方法更新数据:先使用filter过滤,再用update更新:
In [26]: Publisher.objects.filter(id=4)
Out[26]: (0.001) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."id" = 4 LIMIT 21; args=(4,)
[]
In [27]: Publisher.objects.filter(id=4).update(name="麻省理工出版社")
(0.000) BEGIN; args=None
(0.001) UPDATE "hello_publisher" SET "name" = '麻省理工出版社' WHERE "hello_publisher"."id" = 4; args=('麻省理工出版社', 4)
Out[27]: 1
In [28]: print(Publisher.objects.filter(id=4))
(0.000) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."id" = 4 LIMIT 21; args=(4,)
[]
Django 学习日记 - Databse Operation -setp9_第12张图片
update方法更新

2 QuerySet 对象的API

方法 说明
get 返回值是一个modules,仅返回一条数据;如果为空值,会抛出DoesNotExist异常
filter 返回值是一个QuerySet类型的对象
all
order_by
distinct
values 返回的是一个字典
values_list 返回的是一个元组
count

3 关联查询

  1. 多对多关联查询(外联结查询)【双下划线】
In [31]: Book.objects.filter(title="第一本《Python web 开发》").values('authors')
Out[31]: (0.000) SELECT "hello_book_authors"."author_id" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") WHERE "hello_book"."title" = '第一本《Python web 开发》' LIMIT 21; args=('第一本《Python web 开发》',)
[{'authors': 1}]
In [32]: Book.objects.filter(title="第一本《Python web 开发》").values('authors__name')
Out[32]: (0.000) SELECT "hello_author"."name" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") LEFT OUTER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_book"."title" = '第一本《Python web 开发》' LIMIT 21; args=('第一本《Python web 开发》',)
[{'authors__name': '蓝天'}]
Django 学习日记 - Databse Operation -setp9_第13张图片
多对多关联查询(外联结查询)
  1. 多对多关联查询(内链接的查询) 【双下划线】
In [33]: Book.objects.filter(authors__name="蓝天")
Out[33]: (0.118) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") INNER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_author"."name" = '蓝天' LIMIT 21; args=('蓝天',)
[, , ]
>>>
Django 学习日记 - Databse Operation -setp9_第14张图片
多对多关联查询(内链接的查询)
  1. 外键关联查询【双下划线】
>>> AuthorDetail.objects.values('sex','email','address','birthday','author')
(0.001) SELECT `hello_authordetail`.`sex`, `hello_authordetail`.`email`, `hello_authordetail`.`address`, `hello_authordetail`.`birthday`, `hello_authordetail`.`author_id` FROM `hello_authordetail` LIMIT 21; args=()
[{'address': 'www.baidu.com', 'author': 1, 'sex': True, 'birthday': datetime.date(2017, 1, 19), 'email': '[email protected]'}]
>>> AuthorDetail.objects.values('sex','email','address','birthday','author__name')
(0.002) SELECT `hello_authordetail`.`sex`, `hello_authordetail`.`email`, `hello_authordetail`.`address`, `hello_authordetail`.`birthday`, `hello_author`.`name` FROM `hello_authordetail` INNER JOIN `hello_author` ON (`hello_authordetail`.`author_id` = `hello_author`.`id`) LIMIT 21; args=()
[{'address': 'www.baidu.com', 'author__name': '张三2', 'sex': True, 'birthday': datetime.date(2017, 1, 19), 'email': '[email protected]'}]
>>>
Django 学习日记 - Databse Operation -setp9_第15张图片
Paste_Image.png
  1. 主键类访问外键类【_set】,使用的是get的方法
    主键类访问外键类
In [39]: pub = Publisher.objects.get(name="广东人民出版社")
(0.000) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."name" = '广东人民出版社'; args=('广东人民出版社',)
In [40]: pub.book_set.all()
Out[40]: (0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."publisher_id" = 2 LIMIT 21; args=(2,)
[, , ]
Django 学习日记 - Databse Operation -setp9_第16张图片
主键类访问外键类【成功】

外键类访问主键类

In [43]: book = Book.objects.get(title="第十二本《廖雪峰 Python教程》")
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."title" = '第十二本《廖雪峰 Python教程》'; args=('第十二本《廖雪峰 Python教程》',)
In [44]: book.publisher_set.all()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
 in ()
----> 1 book.publisher_set.all()

AttributeError: 'Book' object has no attribute 'publisher_set'
Django 学习日记 - Databse Operation -setp9_第17张图片
外键类访问主键类【失败】

4 聚集查询和分组查询

4.0需要导入的库文件

In [1]: from hello.models import  *
In [2]: from django.db.models import  *

4.1 Count

# 统计名为“广东人民出版社”的出版商的数目
In [3]: Publisher.objects.filter(name="广东人民出版社").aggregate(mycount = Count('name'))
(0.002) SELECT COUNT("hello_publisher"."name") AS "mycount" FROM "hello_publisher" WHERE "hello_publisher"."name" = '广东人民出版社'; args=('广东人民出版社',)
Out[3]: {'mycount': 1}

![Count]](http://upload-images.jianshu.io/upload_images/3982944-c828758817ff50ec.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

4.2 Sum

# 统计姓名为“蓝天”的作者出书的总价
In [6]: Book.objects.filter(authors__name="蓝天").aggregate(Sum('price'))
(0.001) SELECT CAST(SUM("hello_book"."price") AS NUMERIC) AS "price__sum" FROM "hello_book" INNER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") INNER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_author"."name" = '蓝天'; args=('蓝天',)
Out[6]: {'price__sum': Decimal('148.00')}
Django 学习日记 - Databse Operation -setp9_第18张图片
Sum

4.3 values

# 统计每个作者出书的总价
In [7]:  Book.objects.values('authors__name').annotate(Sum('price'))
Out[7]: (0.054) SELECT "hello_author"."name", CAST(SUM("hello_book"."price") AS NUMERIC) AS "price__sum" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") LEFT OUTER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") GROUP BY "hello_author"."name" LIMIT 21; args=()
[{'price__sum': Decimal('392.00'), 'authors__name': None}, {'price__sum': Decimal('10.00'), 'authors__name': '蓝云'}, {'price__sum': Decimal('148.00'), 'authors__name': '蓝天'}, {'price__sum': Decimal('153.00'), 'authors__name': '蓝海'}]
Django 学习日记 - Databse Operation -setp9_第19张图片
values

4.4 Min

# 找出每个出版社里面价格最低的书
In [8]: Book.objects.values('publisher__name').annotate(Min('price'))
Out[8]: (0.000) SELECT "hello_publisher"."name", CAST(MIN("hello_book"."price") AS NUMERIC) AS "price__min" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") GROUP BY "hello_publisher"."name" LIMIT 21; args=()
[{'price__min': Decimal('10.00'), 'publisher__name': '\t广东高等教育出版社'}, {'price__min': Decimal('85.00'), 'publisher__name': '人民教育出版社'}, {'price__min': Decimal('31.00'), 'publisher__name': '广东人民出版社'}, {'price__min': Decimal('28.00'), 'publisher__name': '机械工业出版社'}, {'price__min': Decimal('92.00'), 'publisher__name': '清华大学出版社'}, {'price__min': Decimal('24.00'), 'publisher__name': '电子工业出版社'}, {'price__min': Decimal('87.00'), 'publisher__name': '麻省理工出版社'}]
Django 学习日记 - Databse Operation -setp9_第20张图片
Min

5 使用原生的SQL查询

5.1 extra【QuerySet】对象

结果集修改器,一种提供额外查询参数的机制,结果是一个【QuerySet】对象

In [7]: type(Book.objects.extra(select={'count':'select count(*) from hello_book'}))
Out[7]: django.db.models.query.QuerySet
# 查询广东人民出版社价格大于50的书
In [2]: Book.objects.filter(publisher__name="广东人民出版社").extra(where=["price > 50"])
Out[2]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") WHERE ("hello_publisher"."name" = '广东人民出版社' AND (price > 50)) LIMIT 21; args=('广东人民出版社',)
[, ]
Django 学习日记 - Databse Operation -setp9_第21张图片
extra扩展查询条件
# 查询广东人民出版社价格大于50的书
In [3]: Book.objects.filter(publisher__name='广东人民出版社', price__gt=50)
Out[3]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") WHERE ("hello_publisher"."name" = '广东人民出版社' AND "hello_book"."price" > '50') LIMIT 21; args=('广东人民出版社', Decimal('50'))
[, ]
Django 学习日记 - Databse Operation -setp9_第22张图片
filter的方法实现条件查询
# 汇总书籍表中的书
In [4]: Book.objects.extra(select={'count':'select count(*) from hello_book'})
Out[4]: (0.000) SELECT (select count(*) from hello_book) AS "count", "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" LIMIT 21; args=()
[, , , , , , , , , , , ]
Django 学习日记 - Databse Operation -setp9_第23张图片
extra扩展查询语句

5.2 raw【RawQuerySet】对象

执行原始sql并返回模型实例,最适合用于查询,结果是一个【QuerySet】对象
注意:RawQuerySet也是惰性的,只有在使用的时候才会被执行,特别是insert的时候要注意。

In [9]: type(Book.objects.raw('select * from hello_book'))
Out[9]: django.db.models.query.RawQuerySet
In [14]: for item in Book.objects.raw('select * from hello_book'):
    ...:     print(item)
    ...:
(0.000) select * from hello_book; args=()
第一本《Python web 开发》
第二本《Mysql 高级教程》
第三本《HTML与CSS 高级编程》
第四本《BootStrap 框架》
第五本《Django 框架》
第六本《简明Python教程》
第七本《Python web 开发》
第八本《Mysql 底层原理》
第九本《HTML与CSS 基础教程》
第十本《Flask 框架》
第十一本《Tronado 框架》
第十二本《廖雪峰 Python教程》
第七本《Python web 开发》
Django 学习日记 - Databse Operation -setp9_第24张图片
raw方法查询数据

5.3 直接执行自定义SQL

(这种方式完全不依赖model,前面两种方式还是要依赖于model),适合增删改

In [39]: from django.db import connection

In [40]: cursor = connection.cursor() #获得一个游标(cursor)对象

In [41]: cursor.execute("insert into hello_author(name) values('蓝盾')")
(0.272) insert into hello_author(name) values('蓝盾'); args=None
Out[41]: 

In [42]: cursor.execute("update hello_author set name = '蓝网' where name='蓝盾'")
(0.270) update hello_author set name = '蓝网' where name='蓝盾'; args=None
Out[42]: 

In [43]: cursor.execute("delete from hello_author where name='蓝网'")
(0.247) delete from hello_author where name='蓝网'; args=None
Out[43]: 

In [44]: cursor.execute('select * from hello_author')
(0.000) select * from hello_author; args=None
Out[44]: 

In [45]: print(cursor.fetchone())  #执行结果第一条输出
(1, '蓝天')

In [46]: print(cursor.fetchall()) # 所有执行结果输出,由于第一条已经输出,所以游标从第二条开始
[(2, '蓝海'), (3, '蓝云'), (4, '蓝视')
Django 学习日记 - Databse Operation -setp9_第25张图片
直接执行自定义SQL

你可能感兴趣的:(Django 学习日记 - Databse Operation -setp9)