Django-4

Django-4

模型层(models.py)

​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到一些数据的管理操作(增删改查),而一旦谈到数据的管理操作,就需要用到数据库管理工具,例如mysql,oracle.....

​ 如果应用程序需要操作数据,那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作数据库。

​ 但是直接编写原生sql会严重影响开发效率。为了解决这一问题,Django引入了orm的概念,orm在pymysql之上又进行了一层封装,对于数据的操作,我们无需再去编写原生sql,我们只用基于面向对象的思想去编写类、对象、调用相应的方法,orm会将其映射成
原生sql然后交给pymysql执行。

​ 这样一来,开发人员既不用再去考虑原生sql的优化问题,也不用考虑数据库迁移的问题,orm都帮我们做了优化并且支持多种数据库,这极大的提高了我们的开发效率。

单表操作

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)

首先,在Django中,为了方便,可以配置虚拟的测试环境:

import os


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "one_search.settings")
    import django
    django.setup()

然后,我们就可以在测试环境下编写代码了。

# 增
models.Book.objects.create(title='xx',price=10.50)

obj = models.Book(title='xx',price=10.50)
obj.save

# 删
models.Book.objects.filter(pk=1).delete()

# 改
models.Book.objects.filter(pk=1).update(price=100)
# 也能用obj.save()

必知必会13条

# 查
1.all():查询所有
2.filter():条件查询
3.get():条件查询,查出来的直接是对象
4.first():拿到第一个
5.last():拿到最后一个
6.exclude():除此之外
7.values():列表套字典
8.values_list():列表套元组
9.count():计数
10.distince():去重(数据一模一样才算相同)
11.order_by():排序(默认升序,-是降序)
12.reverse():反装(必须是已经排序好了的才能反转)
13.exists():判断查出来的是否有对象

神奇的双下划线查询

# 查询价格大于200的书籍
res = models.Book.objects.filter(price__gt=200)
# 查询价格小于200的书籍
res = models.Book.objects.filter(price__lt=200)
print(res)
# 查询价格大于或者等于200的书籍
res = models.Book.objects.filter(price__gte=200)
res1 = models.Book.objects.filter(price__lte=200)
print(res,res1)

# 价格是200 或者是123.23 或者666.66
res = models.Book.objects.filter(price__in=[200,123.23,666.66])
print(res)
# 价格在200 到700之间的书籍
res = models.Book.objects.filter(price__range=(200,666.66))  # 顾头不顾尾
print(res)

模糊匹配

"""
    like
    %
    _
"""
# 查询书籍名称中包含p的
res = models.Book.objects.filter(title__contains='p')  # 区分大小写
print(res)
# 忽略大小写
res = models.Book.objects.filter(title__icontains='p')  # 忽略大小写
print(res)

# 查询书籍名称是以三开头的书籍
res = models.Book.objects.filter(title__startswith='三')
res1 = models.Book.objects.filter(title__endswith='P')
print(res1)

# 查询出版日期是2019年的书籍
res = models.Book.objects.filter(publish_date__year='2019')
# 查询出版日期是10月的书籍
res = models.Book.objects.filter(publish_date__month='10')

多表操作

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)
    # 书籍与出版社 是一对多关系
    publish = models.ForeignKey(to='Publish')
    # 书籍与作者 是多对多
    authors = models.ManyToManyField(to='Author')
    """
    authors虚拟字段
        1.告诉orm自动帮你创建第三张关系表
        2.orm查询的时候  能够帮助你更加方便的查询
    """

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # author_detail = models.ForeignKey(unique=True,to='AuthorDetail')
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=64)
# 一对多字段增删改查
# models.Book.objects.create(title='三国演义',price=123.23,publish_id=1)  # publish_id直接传出版社主键值

# publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='水浒传',price=123.23,publish=publish_obj)  # publish直接传出版社数据对象

# 查
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.publish)  # 获取到当前所对应的出版社对象
# print(book_obj.publish_id)  # 获取到的就是表中的实际字段

# 改
# models.Book.objects.filter(pk=1).update(publish_id=3)
# publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.filter(pk=1).update(publish=publish_obj)

# 删除
# models.Publish.objects.filter(pk=2).delete()
# 默认也是级联更新 级联删除
# 多对多字段的增删改查

# 给主键为3的书籍添加两个作者 1 2
# book_obj = models.Book.objects.filter(pk=3).first()
# # print(book_obj.authors)  # 就相当于 已经在书籍和作者的关系表了
# # book_obj.authors.add(1)
# # book_obj.authors.add(2,3)
# author_obj = models.Author.objects.filter(pk=1).first()
# author_obj1 = models.Author.objects.filter(pk=2).first()
# # book_obj.authors.add(author_obj)
# book_obj.authors.add(author_obj,author_obj1)
"""
    add() 括号内既可以传数字也可以传数据对象
    并且都支持传多个
    """


# 修改关系
# book_obj = models.Book.objects.filter(pk=3).first()
# # book_obj.authors.set([3,])
# # book_obj.authors.set([1,3])
# author_obj = models.Author.objects.filter(pk=1).first()
# author_obj1 = models.Author.objects.filter(pk=2).first()
# book_obj.authors.set((author_obj,))
# book_obj.authors.set((author_obj,author_obj1))
"""
    set() 括号内 既可以传数字也传对象 
    并且也是支持传多个的
    但是需要注意 括号内必须是一个可迭代对象
    """

# 删
# book_obj = models.Book.objects.filter(pk=3).first()
# # book_obj.authors.remove(2)
# # book_obj.authors.remove(1,2)
#
# author_obj = models.Author.objects.filter(pk=1).first()
# author_obj1 = models.Author.objects.filter(pk=2).first()
# # book_obj.authors.remove(author_obj)
# book_obj.authors.remove(author_obj,author_obj1)
"""
    remove() 括号内 既可以传数字也传对象 
    并且也是支持传多个的
    """
# 清空
# book_obj = models.Book.objects.filter(pk=3).first()
# book_obj.authors.clear()
"""clear()括号内不需要传任何参数 直接清空当前书籍对象所有的记录"""
"""
    ORM跨表查询
        1.子查询
        2.连表查询
        
    正反向的概念
        外键字段在谁那儿 由谁查谁就是正向
        
        谁手里有外键字段 谁就是正向查
        没有外键字段的就是反向
        书籍对象 查  出版社    外键字段在书籍       正向查询
        出版社 查 书籍         外键字段在书籍       反向查询
        
        
        正向查询按字段
        反向查询按表名小写 ...
        
"""

 # 1.基于对象的跨表查询    子查询
    # 1.查询书籍是python入门的出版社名称
    # book_obj = models.Book.objects.filter(title='python入门').first()
    # # 正向查询按字段
    # print(book_obj.publish.name)
    # print(book_obj.publish.addr)
    # 2.查询书籍主键是6的作者姓名
    # book_obj = models.Book.objects.filter(pk=6).first()
    # # print(book_obj.authors)  # app01.Author.None
    # print(book_obj.authors.all())
    # 3.查询作者是jason的手机号
    # author_obj = models.Author.objects.filter(name='jason').first()
    # print(author_obj.author_detail.phone)
    # print(author_obj.author_detail.addr)
    """
    正向查询 按字段 
    当该字段所对应的数据有多个的时候 需要加.all()
    否者点外键字段直接就能够拿到数据对象
    """
    # 4.查询出版社是东方出版社出版过的书籍
    # publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    # # print(publish_obj.book_set)  # app01.Book.None
    # print(publish_obj.book_set.all())
    # 5.查询作者是jason写过的所有的书
    # author_obj = models.Author.objects.filter(name='jason').first()
    # # print(author_obj.book_set)  # app01.Book.None
    # print(author_obj.book_set.all())
    # 6.查询手机号是110的作者
    # author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
    # print(author_detail_obj.author)
    # print(author_detail_obj.author.name)
    # print(author_detail_obj.author.age)
    """
    反向查询按表名小写 
        什么时候需要加_set
            当查询的结果可以是多个的情况下 需要加_set.all()
        什么时候不需要加_set
            当查询的结果有且只有一个的情况下 不需要加任何东西 直接表名小写即可
    """
    # 7.查询书籍是python入门的作者的手机号
    # book_obj = models.Book.objects.filter(title='python入门').first()
    # print(book_obj.authors.all())

    # 2.基于双下划綫的跨表查询   连表查询
    """
    MySQL
        left join
        inner join
        right join
        union
    """
    # 1.查询书籍是python入门的出版社名称
    # 正向
    # res = models.Book.objects.filter(title='python入门').values('publish__name')
    # print(res)
    # 反向
    # res = models.Publish.objects.filter(book__title='python入门').values('name')
    # print(res)


    # 2.查询作者是jason的手机号码
    # 正向
    # res1 = models.Author.objects.filter(name='jason').values('author_detail__phone')
    # print(res1)
    # 反向
    # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age')
    # print(res)



    # 3.查询手机号是120的作者姓名

    # res2 = models.AuthorDetail.objects.filter(phone=120).values('author__name')
    # print(res2)
    # res = models.Author.objects.filter(author_detail__phone=120).values('name','author_detail__addr')
    # print(res)


    # 4.查询出版社是东方出版社出版的书籍名称
    # res = models.Publish.objects.filter(name='东方出版社').values('book__title','addr')
    # print(res)
    # 5.查询作者是jason的写过的书的名字和价格
    # res = models.Author.objects.filter(name='jason').values('book__title','book__price')
    # print(res)

    # 7.查询书籍是python入门的作者的手机号
    # res = models.Book.objects.filter(title='python入门').values('authors__author_detail__phone')
    # print(res)
posted @ 2019-10-28 22:18  SweetJack  阅读(170)  评论(0编辑  收藏  举报