ORM介绍 及 案例
1. ORM已经的学过的内容: 1. Django项目如何使用ORM连接MySQL 1. 手动创建数据库 2. 在settings.py里面配置一下数据库的连接信息(告诉Django连接哪一个数据库) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 连接数据库的类型 'NAME': 'day62xiawu', # 数据库名字 'HOST': '127.0.0.1', # IP 'PORT': 3306, # 端口 'USER': 'root', # 用户名 'PASSWORD': '123456', # 密码 } } 3. 在和settings.py同目录下的__init__.py文件中,告诉Django用pymysql代替MySQLdb来连接数据库 import pymysql pymysql.install_as_MySQLdb() 4. 在app/models.py中,定义类,类一定要继承models.Model class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32) 5. 执行两条命令 1. 在哪儿执行? 在项目的根目录(有manage.py文件的那个目录) 2. 命令 python manage.py makemigrations --> 将models.py文件中的改动记录在小本本(app/migrations/00xx_****.py)上 python manage.py migrate --> 将改动翻译成SQL语句,去数据库中执行 2. 表和表之间的关系 1. 一对多(出版社和书) publisher = models.ForeignKey(to="Publisher") 在数据库中: 有没有publisher这个字段? 数据库中实际 生成的是一个 publisher_id 字段 2. 多对多(作者和书) books = models.ManyToManyField(to="Book") 在数据库中: 是通过第三张表建立的关系 3. 增删改查操作 1. 单表增删改查 增: models.Publisher.objects.create(name="沙河出版社") 查: models.Publisher.objects.get(id=1) models.Publisher.objects.get(name="沙河出版社") 删: models.Publisher.objects.get(id=1).delete() 改: obj = models.Publisher.objects.get(id=1) obj.name = "沙河第二出版社" obj.save() 2. 外键的增删改查 增、删、查同上 book_obj = models.Book.objects.get(id=1) book_obj.publisher 是什么? ***** 和我这本书关联的出版社对象 book_obj.publisher.id 和我这本书关联的出版社的id值 book_obj.publisher.name 和我这本书关联的出版社的名称 book_obj.publisher_id 是什么? 和我这本书关联的出版社的id值 3. 多对多操作 1. 查id为1的作者都写过的书? author_obj = models.Author.objects.get(id=1) author_obj.books.all() --> 和我这个作者关联的所有书对象 2. 想给作者绑定多本书? author_obj = models.Author.objects.get(id=1) author_obj.books.set([1,2,3]) --> 把id是1、2、3的书和我这个作者关联上 2. 今日内容 1. Django ORM常用字段: 1. AutoField --> 自增 2. CharField --> varchar(xx) 3. ForeignKey --> 外键 4. ManyToManyField --> 多对多关联 5. DateField 6. DateTimeField 7. IntegerField 2. 自定义char字段 class FixedCharField(models.Field): """ 自定义的char类型的字段类 """ def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection): """ 限定生成数据库表的字段类型为char,长度为max_length指定的值 """ return 'char(%s)' % self.max_length 3. 常用的字段参数 1. null 2. default 3. unique 4. db_index 5. DateField和DateTimeField才有的参数: auto_now_add=True --> 创建数据的时候自动把当前时间赋值 auto_add=True --> 每次更新数据的时候更新当前时间 上述两个不能同时设置!!! 5. class Meta: db_table = "表名"
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 查询所有的人 15 ret1 = models.Person.objects.all() 16 17 # 用get加条件查询,查不到会报错,今后都用filter居多 18 ret2 = models.Person.objects.get(id=5) # 可查任何字段,此处以id字段为例 19 20 # 用filter查询 21 ret3 = models.Person.objects.filter(id__gt=2) # 查询id大于2的结果集 22 ret4 = ret3[0] 23 ret5 = models.Person.objects.filter(name="张三") # 查询名叫张三的人,没有返回空,不会报错 24 25 # exclude 不包含查询 26 ret6 = models.Person.objects.exclude(name="小黑") # 查询姓名除了小黑以外的人 27 28 # values 取字段列的值 返回字典序列 29 ret7 = models.Person.objects.values("name", "birthday") 30 31 # value_list 取字段列的值 返回元组 32 ret8 = models.Person.objects.values_list("name", "birthday") 33 34 # order_by 指定字段排序 35 ret9 = models.Person.objects.all().order_by("age") 36 37 # reverse 对一个有序的QuerySet进行反转,相当于要有了order_by再反转 38 ret10 = ret9.reverse() 39 40 # count 获取数量 41 ret11 = ret10.count() 42 43 # first 获取第一个值 44 ret12 = ret10.first() 45 46 # last 获取最后一个值 47 ret13 = ret10.last() 48 49 # exists 判断是不是空表,返回布尔值 50 ret14 = ret10.exists()
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 查询所有的人 15 ret1 = models.Person.objects.all() 16 17 # 查询id大于1小于4的人 18 ret2 = ret1.filter(id__gt=1, id__lt=4) 19 20 # 查询在指定范围的值 in 21 lis = [3, 5, 6] 22 ret3 = ret1.filter(id__in=lis) 23 24 # 查询不在指定范围的值 not in 25 ret4 = ret1.exclude(id__in=lis) 26 27 # 模糊查询,大小写敏感 28 ret5 = ret1.filter(name__contains="小") 29 30 # 模糊查询,不分大小写 31 ret6 = ret1.filter(name__icontains="j") 32 33 # between and 34 ret7 = ret1.filter(age__range=(18, 28)) 35 36 # 类似的还有startswith, istartswith, endswith, iendswith 37 38 # date字段可以把年月日单独拿出来判断 39 ret8 = ret1.filter(birthday__year=2018) # 查询2018年生日的人 40 ret9 = ret1.filter(birthday__month=5) # 查询5月份生日的人 41 ret10 = ret1.filter(birthday__year=2005, birthday__month=1, birthday__day=13) # 查询2005年1月13日生日的人
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 外键——正向查询 15 # 查询ID是1的出版社的名称 方法一 基于对象跨表 16 book_obj = models.Book.objects.first() 17 ret1 = book_obj.publisher # 对象类型 18 ret2 = ret1.name # 字符串类型 19 20 # 查询ID是1的出版社的名称 方法二 利用双下划线跨表 21 # 双下划线表示跨了一张表 22 ret3 = models.Book.objects.filter(id=1).values_list("publisher__name") 23 24 25 # 外键——反向查询 26 # 查询第一个出版社关联的所有书籍 基于对象 27 publisher_obj = models.Publisher.objects.first() # 得到一个具体的对象 28 ret4 = publisher_obj.books.all() # books是前面models建表时related_name="books"
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 多对多 15 author_obj = models.Author.objects.first() 16 # print(author_obj) 17 # 18 # # 查询金老板写过的书 19 # ret = author_obj.books.all() 20 # print(ret) 21 22 # 1.create 23 # 通过作者创建一本书 24 # 1.在book表里面创建一本新书 2.在作者和书的关系表中添加关联记录 25 # author_obj.books.create(title="程宝露自传", publisher_id=2) 26 27 28 # 2.add 29 30 # 在金老板关联的书里面,再加一本ID是4的书 31 # book_obj = models.Book.objects.get(id=4) 32 # author_obj.books.add(book_obj) 33 34 # 添加多个 35 # book_objs = models.Book.objects.filter(id__gt=5) 36 # author_obj.books.add(*book_objs) # 要把列表打散再传进去 37 38 # 直接添加ID 39 # author_obj.books.add(9) 40 41 42 # remove 删除 43 # 从金老板关联的书里面删除 44 # book_obj = models.Book.objects.get(title="跟金老板学开摩托") 45 # author_obj.books.remove(book_obj) 46 47 # 用ID来删除 48 # author_obj.books.remove(8) 49 50 # clear 51 # 清空 52 # 把景女神关联的书都删掉 53 # jing_obj = models.Author.objects.get(id=2) 54 # jing_obj.books.clear()
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 聚合查询 15 16 from django.db.models import Avg, Sum, Max, Min 17 ret1 = models.Book.objects.all().aggregate(price_avg=Avg("price")) 18 # 多个聚合 19 ret2 = models.Book.objects.all().aggregate(price_avg=Avg("price"), price_max=Max("price"), price_min=Min("price")) 20 21 ret3 = ret2.get("price_avg") # 取字典值
1 """ 2 ORM小练习 3 """ 4 import os 5 6 if __name__ == '__main__': 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_ex.settings") 8 import django 9 10 django.setup() 11 12 from app01 import models 13 14 # 聚合查询 15 16 from django.db.models import Avg, Sum, Max, Min 17 18 19 20 # 查找所有书名里包含番茄的书 21 models.Book.objects.filter(title__contains="番茄") 22 23 24 # 查找出版日期是2017年的书 25 models.Book.objects.filter(publish_date__year=2017) 26 27 28 # 查找出版日期是2017年的书名 29 30 31 32 # 查找价格大于10元的书 33 models.Book.objects.filter(price__gt=10) 34 35 36 # 查找价格大于10元的书名和价格 37 38 39 40 # 查找memo字段是空的书 41 42 43 44 # 查找在北京的出版社 45 models.Publisher.objects.filter(city="北京") 46 47 48 # 查所有书关联的出版社 49 ret = models.Book.objects.all().values_list("publisher__name") 50 # ret得到的出版社可能会有重复的出版社名称,此时我们就可以用distinct去重: 51 ret2 = ret.distinct() 52 53 54 # 将所有的书价格按照倒序排序 55 ret = models.Book.objects.all().order_by("price").reverse() 56 # 或者用-负号表示倒序 57 ret = models.Book.objects.all().order_by("-price") 58 59 60 61 # 查找名字以沙河开头的出版社 62 63 64 65 # 查找作者名字里面带“小”字的作者 66 67 68 69 # 查找年龄大于30岁的作者 70 71 72 73 # 查找手机号是155开头的作者 74 75 76 77 # 查找手机号是155开头的作者的姓名和年龄 78 79 80 81 # 查找书名是“番茄物语”的书的出版社 82 83 84 85 # 查找书名是“番茄物语”的书的出版社所在的城市 86 ret = models.Book.objects.filter(title="番茄物语").values("publisher__city") 87 88 89 90 # 查找书名是“番茄物语”的书的出版社的名称 91 92 93 94 95 96 # 查找书名是“番茄物语”的书的作者的爱好(跨两张表) 97 ret = models.Book.objects.filter(title="番茄物语").values("author__detail__hobby") 98 99 100 101 # 查找书名是“番茄物语”的书的所有作者 102 103 104 105 # 查找书名是“番茄物语”的书的作者的年龄 106 107 108 109 # 查找书名是“番茄物语”的书的作者的手机号码 110 111 112 113 # 查找书名是“番茄物语”的书的作者的地址 114 115 116 117 # 查找书名是“番茄物语”的书的作者的邮箱
1 # 批量创建 2 # 有100个书籍对象 3 objs = [models.Book(title="沙河{}".format(i)) for i in range(100)] 4 5 # 在数据库中批量创建 6 models.Book.objects.bulk_create(objs, 10)
理解ORM:
python中的类 -------------------------- 数据库中的表
对象 -------------------------- 数据行
属性 -------------------------- 字段
ORM能做的事儿:
1.操作数据表:对表创建、修改、删除
2.操作数据行:增、删、改、查
不能创建数据库
使用Django的ORM步骤:
1.自己动手创建数据库

2.在Django项目中配置连接该数据库
settings.py

3.告诉python用pyMySql连接数据库

4.创建类(创建数据表) 这个类必须继承models.Model
app中的models.py

5.将上面的表创建到数据库中(执行两个命令)
Terminal:
python manage.py makemigrations (该命令会在 migrations 文件夹中记录你对models.py的操作,每执行一条该命令会生成一个文件)
python manage.py migrate (把代码翻译成sql执行语句并执行)
把表注释了,再执行上面两行命令就相当于删除表。
表创建完后,可以尝试在navigat中修改字段啥的,没试过,可以试试
6.PyCharm连接数据库

(查) 将数据库数据展示到网页

1.配置urls.py

2.配置views.py

3.配置user_list.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>用户列表</title> 6 </head> 7 <body> 8 9 <a href="/add_user/">添加用户</a> 10 11 <table border="1"> 12 <thead> 13 <tr> 14 <th>id值</th> 15 <th>用户名</th> 16 </tr> 17 </thead> 18 <tbody> 19 {% for user in user_list %} 20 <tr> 21 <td>{{ user.id }}</td> 22 <td>{{ user.name }}</td> 23 </tr> 24 {% endfor %} 25 26 </tbody> 27 </table> 28 </body> 29 </html>
(增) 添加新用户
1.配置urls.py

2.配置add_user.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>添加用户</title> 6 </head> 7 <body> 8 <form action="/add_user/" method="post"> 9 <p>用户名: 10 <input type="text" name="username"> 11 </p> 12 13 <p> 14 <input type="submit" value="提交"> 15 </p> 16 </form> 17 </body> 18 </html>
3.配置views.py
1 def add_user(request): 2 if request.method == "POST": 3 # 用户填写了新的用户名,并发送了POST请求 4 new_name = request.POST.get("username", None) # HTML中input标签中的username 5 # 去数据库中新创建一条用户添加的记录 6 models.UserInfo.objects.create(name=new_name) 7 # return HttpResponse("添加成功") 8 return redirect("/user_list/") # 添加成功后直接跳转到用户列表页 9 10 # 第一次请求页面时,返回一个添加用户的页面 11 return render(request, "add_user.html")
未完

浙公网安备 33010602011771号