Django_ORM知识梳理

#Sql数据库结构

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sakila             |
| stie_28            |
| sys                |
| world              |
+--------------------+
7 rows in set (0.00 sec)

mysql> use stie_28;
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_stie_28          |
+----------------------------+
| app1_author                |
| app1_book                  |
| app1_book_author           |
| app1_publish               |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
14 rows in set (0.00 sec)

mysql> select * from app1_book;
+----+--------+--------+-------+------------+
| id | title  | price  | count | publish_id |
+----+--------+--------+-------+------------+
|  1 | python | 100.00 |   100 |          1 |
|  3 | Linux  | 200.00 |    99 |          2 |
|  7 | linux2 | 200.00 |   100 |          1 |
|  8 | abcn   |  67.00 |    38 |          1 |
+----+--------+--------+-------+------------+
4 rows in set (0.00 sec)

mysql> select * from app1_author;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
|  2 | 李四 |
|  3 | 王五 |
+----+------+
3 rows in set (0.00 sec)

mysql> select * from app1_book_author;
+----+---------+-----------+
| id | book_id | author_id |
+----+---------+-----------+
| 26 |       3 |         1 |
| 27 |       3 |         2 |
| 28 |       3 |         3 |
+----+---------+-----------+
3 rows in set (0.00 sec)

mysql> select * from app1_publish;
+----+------------+---------+
| id | name       | address |
+----+------------+---------+
|  1 | 人民出版社 | 北京    |
|  2 | 出版社A    | 北京    |
+----+------------+---------+
2 rows in set (0.00 sec)

mysql>
#Django models.py文件内容

from django.db import models

# Create your models here.

#book与publish外键(一个出版社对应多本书)
class Publish(models.Model):
    name=models.CharField(max_length=32)
    address=models.CharField(max_length=32)

    # def __str__(self):      #直接print publish_obj的时候显示具体的数值
    #     return self.name+' '+self.address

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=9,decimal_places=2)
    count=models.IntegerField()
    #下面的括号内的publish加上""就可以,不用管上下顺序关系,否则必须book必须写在publish下面
    publish=models.ForeignKey('Publish')     #设置publish为外键,django会自动在数据库中加上_id(publish_id)
    author=models.ManyToManyField('Author')  #书跟作者是多对多的关系,使用ManyToMany让django自动创建第三张关系表
    def __str__(self):
        return self.title

class Author(models.Model):
    name=models.CharField(max_length=32)

#手动创建的书跟出版社多对多的关系的第三张表
# class BooktoPublish(models.Model):
#     book=models.ForeignKey("Book")
#     publish=models.ForeignKey("Publish")
#Django views.py文件内容

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
from app1.models import *

def add(request):
    # 向出版社表中插入数据
    # p=Publish(name="人民出版社",address="北京")
    # p.save()
    # 向作者表中插入数据
    # Author.objects.create(
    #     name='李四'
    # )

    # 两种向表中插入数据的方式
    # 一. save()方式
    # publish_obj=Publish.objects.get(id=1)   #获取出版社表中的条目ID对象(对应ID必须存在)
    #
    # print("publish_obj:",publish_obj)   #publish_obj是一个 Publish object,可以通过 在class中使用 __str__(self)显示具体数据
    # book_obj=Book(title="python",price=100.00,count=100,publish=publish_obj)    #给外键赋值的两种办法这里使用对象来赋值,所以写成publish=''
    # book_obj.save()
    # # 二. create方式
    # Book.objects.create(
    #     title="linux2",
    #     price=200.00,
    #     count=100,
    #     publish_id=1   #给外键赋值的第二种方式,使用publish_id直接指定ID数值(publish的对应ID必须存在)
    # )

    # 添加多对多关系
    # 正向绑定
    # book_Obj_linux=Book.objects.get(title='Linux')   #获取书对象
    # author_obj_1=Author.objects.get(id=1)   #获取作者对象
    # author_obj_2=Author.objects.get(id=2)
    # author_obj_list=Author.objects.all()   #获取所有作者对象

    # print("===========",author_obj_list)    #这是获取到的作者对象数据形式,QuerySet类型
    # <QuerySet [<Author: Author object>, <Author: Author object>, <Author: Author object>]>

    # 绑定关系
    # book_Obj_linux.author.add(author_obj_1,author_obj_2)   #绑定单个或者用逗号隔开多个作者
    # book_Obj_linux.author.remove(author_obj_1,author_obj_2) #移除单个或者用逗号隔开多个作者
    # book_Obj_linux.author.add(*author_obj_list) #添加集合形式需要在前面加上*号

    # 反向绑定
    # author_obj_zhangsan=Author.objects.get(name='张三')   #获取作者对象
    # author_obj_zhangsan.book_set.add(*Book.objects.all())   #作者写了所有书
    # author_obj_zhangsan.book_set.add(*Book.objects.filter(id=2))  #作者只写了ID为2的书

    # 解除绑定
    # book_Obj_linux.author.clear()   #解除书籍绑定的对应的所有作者关系

    # author=Author.objects.get(id=2)   #获取author对象
    # book_Obj_linux.author.remove(author)  #移除 book_obj_linux的对应作者
    # book_Obj_linux.delete()   #删除 book_obj_linux

    return HttpResponse("ok")

def query(request):
    # 查询方法
    # 一. all()
    # ret=Book.objects.all() #<QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
    # 查询的所有书籍对象,可以在model中 配置def __str__(self)属性显示具体书名
    # <QuerySet [<Book: python>, <Book: Linux>, <Book: linux2>]>配置后查询结果

    # 二. filter()
    # ret=Book.objects.filter(price=200,count__gt=100)  #<QuerySet [<Book: python>]>
    # 过滤查询,filter后面括号内为过滤条件,多个条件逗号隔开

    # 三. get()
    # ret=Book.objects.get(id=1)
    # 获取 title=Linux 的记录,直接返回获取的属性值Linux
    # 注:不能get有多个结果的字段值,例如有多个count等于100

    # 四. exclude()
    # ret=Book.objects.exclude(id=1)  # <QuerySet [<Book: Linux>, <Book: linux2>]>
    # 获取与筛选条件不匹配的对象,上面ID=1的是Python ,筛选出另外两个

    # 了不起的双下划线
    # -----------------单表条件查询------------------------
    # ret=Book.objects.filter(id__lt=7,id__gt=1) # <QuerySet [<Book: Linux>]>
    # 查询book表中id小于7 大于1的条目.
    # ret=Book.objects.filter(id__in=[1,3,7])  # <QuerySet [<Book: python>, <Book: Linux>, <Book: linux2>]>
    # 查询id 等于 1 3 7的条目,使用exclude可以达到  not in  不等于取反的效果
    # ret=Book.objects.filter(title__icontains='linux')  #<QuerySet [<Book: Linux>, <Book: linux2>]>
    # __icontains不区分大小写,含包含功能所以匹配到两个结果
    # ret = Book.objects.filter(title__contains='Linux')  # <QuerySet [<Book: Linux>]>
    # contains匹配一个条目,区分大小写
    # ret=Book.objects.filter(id__range=[1,7])  # <QuerySet [<Book: python>, <Book: Linux>, <Book: linux2>]>
    # 匹配id 1-7 之间 包含1 和 7
    # ret=Book.objects.filter(title__startswith='L') # <QuerySet [<Book: Linux>]>
    # 匹配L开头的title,只显示找到的第一个条目
    # ret=Book.objects.filter(title__endswith='n') # <QuerySet [<Book: python>, <Book: abcn>]>
    # 匹配n结尾的title

    # istartswith,iendswith   <----这两个跟上面一样只是 忽略大小写

    # ----------------多表条件关联查询---------------------
    # 正向查找
    # 一对多
    # <QuerySet [{'publish__address': '北京'}]>
    # ret=Book.objects.filter(id=1).values('publish__address')
    # 查询出版了id=1的书籍的所有出版社地址
    #
    # 多对多
    # <QuerySet [{'author__name': '张三'}, {'author__name': '李四'}, {'author__name': '王五'}]>
    # ret=Book.objects.filter(title='Linux').values('author__name')
    # 查询title=Linux的书籍的所有作者姓名
    #
    # 反向查找
    # 一对多
    # <QuerySet [{'book__title': 'python'}, {'book__title': 'linux2'}]>
    # ret=Publish.objects.filter(id=1).values('book__title')
    # 查询ID=1的出版社,出版的所有书籍
    #
    # 反向多对多
    # <QuerySet [{'book__title': 'Linux'}]>
    # ret=Author.objects.filter(id=1).values('book__title')
    # 查询id=1的作者,写了哪些书籍

    # -------------------QuerySet相关 --------------------------

    # QuerySet集合支持切片操作
    # ret=Book.objects.all()[0]    #python  取集合索引为零
    # ret=Book.objects.all()[0:2]  #<QuerySet [<Book: python>, <Book: Linux>]>  取集合索引0-2的不含2
    # ret=Book.objects.all()[2]    #linux2
    # ret=Book.objects.all()[::2]    #[<Book: python>, <Book: linux2>]   隔两个取一个
    # print(ret)

    # QuerySet可迭代
    # book_list=Book.objects.all()
    #
    # for book in book_list:    # for 循环没循环一次访问一次数据库(执行一次sql语句)取出对应的数据
    #     print(book.title)
    #
    # if book_list:               # if在判断的时候也执行了sql语句,来判断book_list是否有值
    #     print('Have values')

    # -------------查询借助对象以及属性--------------------
    # book_obj=Book.objects.get(title='python')
    # print(book_obj.publish.address)  # 北京
    # 查询Python这本书的出版社地址

    # book_obj=Book.objects.get(title='Linux')  # 获取书籍对象
    # author_list=book_obj.author.all()     # 获取这本书的所有作者集合(QuerySet类型)
    # for author in author_list:            # 循环打印出所有作者的名字
    #     print(author.name)   # 张三 李四  王五
    # 查询Linux这本书的所有作者

    # 反向查询
    # publish_obj=Publish.objects.get(name='人民出版社')  #获取出版社对象
    # book_list=publish_obj.book_set.all()     #获取出版社下的所有书籍集合(QuerySet类型)
    # for book in book_list:                   #for循环取出所有的书名
    #     print(book.title)  #python linux2 abcn
    # 查询人民出版社出版了哪些书


    return HttpResponse("query ok")
# 八月三十日追加views内容

def aggregate(request):
    # -------------------聚合查询和分组查询------------------
    from django.db.models import Avg,Min,Sum,Max

    # ret=Book.objects.all().aggregate(AvgPrice=Avg('price'))  # {'price__avg': 141.75}
    # 求所有书籍的平均价格   AvgPrice=Avg() 前面为自定义键名         ↑ 这是不指定键名自动生成的键名
    # ret = Book.objects.all().aggregate(MaxPrice=Max('price'))  # {'MaxPrice': Decimal('200.00')}
    # 求所有书籍的最高价格                                          ↑ MaxPrice为指定的键名
    # ret=Book.objects.filter(author__name='张三').aggregate(Max('price'))  # {'price__max': Decimal('200.00')}
    # 求张三出版的所有书籍最高价格是多少
    # ret=Book.objects.values('author__name').annotate(Max('price')) # <QuerySet [{'author__name': '张三', 'price__max': Decimal('200.00')}, {'author__name': '李四', 'price__max': Decimal('199.00')},....
    # 查询每个作者出版的价格最高的书籍           ↑  这是聚合相当于 group_by
    # ret=Book.objects.values('publish__name').annotate(Min('price')) # <QuerySet [{'publish__name': '人民出版社', 'price__min': Decimal('67.00')}, {'publish__name': '出版社A', 'price__min': Decimal('199.00')}]>
    # 查询每个出版社出版过的书中价格最低的书

    return HttpResponse("aggregate ok")

def FandQ(request):
    from django.db.models import F,Q  # 导入models下的F,Q

    # ret=Book.objects.all().update(price=F("price") + 20)   # update会返回更改了几条记录   4
    # 给所有书籍的价格加上20                ↑  F相当于临时变量,获取原本的 price数值
    # ret=Book.objects.filter(Q(title__startswith='L')|Q(price__gt=200))  # <QuerySet [<Book: python>, <Book: Linux>, <Book: Linux2>]>
    # 查询书名是L开头的 或者价格大于 200的书籍         |管道符是或的意思   ,逗号是且的意思    Q给条件分组用于复杂查询
    return HttpResponse("FandQ ok")

 

附:

# 查询相关API:

#  <1>filter(**kwargs):      它包含了与所给筛选条件相匹配的对象

#  <2>all():                 查询所有结果

#  <3>get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

#-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()--------

#  <4>values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列
                                     
#  <5>exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象

#  <6>order_by(*field):      对查询结果排序

#  <7>reverse():             对查询结果反向排序

#  <8>distinct():            从返回结果中剔除重复纪录

#  <9>values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

#  <10>count():              返回数据库中匹配查询(QuerySet)的对象数量。

#  <11>first():               返回第一条记录

#  <12>last():                返回最后一条记录

#  <13>exists():             如果QuerySet包含数据,就返回True,否则返回False
#在settings加上日志记录部分

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

 

posted @ 2017-08-28 22:22  neuropathy_ldsly  阅读(198)  评论(0)    收藏  举报