ORM介绍 及 案例

ORM介绍和字段及字段参数 

 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 = "表名"
ORM增删改笔记
 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>
user_list

 

 

 

(增) 添加新用户

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>
add_user

 

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")
add_user函数

 

 

未完

 

  

 

posted @ 2018-12-11 21:43  宝露  阅读(319)  评论(0)    收藏  举报