Django之Orm操作数据

Posted yuyafeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之Orm操作数据相关的知识,希望对你有一定的参考价值。

单表操作

数据表book表

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)
    publish = models.ForeignKey(to=Publish)
    author = models.ManyToManyField(to=Author)

    def __str__(self):
        return self.title

数据表publish表

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

数据表author表

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    authordetail = models.OneToOneField(to=AuthorDetail)

数据表authordetail表

class AuthorDetail(models.Model):
    addr = models.CharField(max_length=32)
    phone = models.CharField(max_length=32)

 

task.py中操作初始化

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day3.settings")
    import django
    django.setup()
    from app1 import models  # 这一句话必须在这下面导入

 

单表操作

create  基于queryset    返回queryset对象
obj = models.Publish.objects.create(name=西方方出版社,addr=西方方,email=[email protected])
models.Book.objects.create(title=三国演义, price=66.66,publish_id=4)

save 基于对象绑定  返回改数据对象
obj = models.Book(title=金瓶,price=55.55,publish_id=1)
obj.save()

update  基于queryset   返回修改的条数 
models.Book.objects.filter(pk=1).update(price=99.99)

save 基于对象绑定   obj为改数据对象
obj = models.Book.objects.filter(pk=1).first()
obj.price = 1000
obj.save()

delete   基于queryset   返回修改的条数(如有外键也会返回外表删除的条数)
obj = models.Book.objects.get(pk=7).delete() print(obj)

all 查全部 返回queryset
obj = models.Book.objects.all()

first 第一条 返回改数据对象
obj = models.Book.objects.all().first()

last 最后一条 返回该数据对象
obj = models.Book.objects.all().first()

filter 查条件匹配 返回queryset
obj = models.Book.objects.filter(pk=1).first()

get 查询一条数据 超过一条或没有则报错  返回对象
obj = models.Book.objects.get(id=1)

exists 判断queryset是否有数据  返回True或 False
obj = models.Book.objects.filter(pk=1).exists()

exclude 除掉匹配的条件所有的数据  返回queryset
obj = models.Book.objects.exclude(pk=1)
obj = models.Book.objects.exclude(pk=-1)   -1为降序  

order_by 排序 返回queryset
obj = models.Book.objects.all().order_by(price)

reverse  反向排序 返回queryset
obj = models.Book.objects.all().order_by(price).reverse()
obj = models.Book.objects.all().reverse()

count 统计查出数据的条数  返回int
obj = models.Book.objects.all().count()

value 查看字段 返回queryset  一个字典序列  只有value中的字段
obj = models.Book.objects.all().values(title)

value 查看字段 返回queryset   一个元组序列  只有value中的字段
obj = models.Book.objects.all().values_list(title)

distinct 返回结果中剔除重复纪录  去重的对象必须是完全相同的数据才能去重 返回queryset
obj = models.Book.objects.all().distinct()

双下划线查询

__gt  大于   返回queryset对象
models.Book.objects.filter(price__gt=60)

__lt  小于   返回queryset对象
models.Book.objects.filter(price__lt=60)

__gte  大于等于   返回queryset对象
models.Book.objects.filter(price__gte=66.66)

__lte  小于等于   返回queryset对象
models.Book.objects.filter(price__lte=66.66)

__in   在某些数字之内   返回queryset对象
models.Book.objects.filter(price__in=[66.66,77.77])

__range  在两个数字范围内   返回queryset对象
models.Book.objects.filter(price__range=[0,100])
__year   判断年份等于   返回queryset对象
models.Book.objects.filter(publish_date__year=2019)
__month 判断月份等于 返回queryset对象 models.Book.objects.filter(publish_date__month
=6)
__day 判断日等于 返回queryset对象 models.Book.objects.filter(publish_date__day
=13)
__week_day 判断星期 返回queryset对象 models.Book.objects.filter(publish_date__week_day
=4)
__contains 获取字段是否包含xx的数据  返回queryset对象
models.Book.objects.filter(title__contains=)
__icontains 获取字段是否包含xx(无视大小写)的数据 返回queryset对象 models.Book.objects.filter(title__icontains
=E)
__startswith 获取字段是否以xx开头的数据 返回queryset对象 models.Book.objects.filter(title__startswith
=)
__endswith 获取字段是否以xx结尾的数据 返回queryset对象 models.Book.objects.filter(title__endswith
=)

 

多表操作

多表查询
      表与表之间的关系
            一对一(OneToOneField):一对一字段无论建在哪张关系表里面都可以,但是推荐建在查询频率比较高的那张表里面
            一对多(ForeignKey):一对多字段建在多的那一方
            多对多(ManyToManyField):多对多字段无论建在哪张关系表里面都可以,但是推荐建在查询频率比较高的那张表里面
            ps:如何判断表与表之间到底是什么关系
            换位思考
                A能不能有多个B
                B能不能有多个A

 

一对多

增
基于id   返回该数据对象
obj = models.Book.objects.create(title=葫芦娃,price=11.11,publish_id=2)
基于对象   返回该数据对象
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.create(title=凹凸曼,price=22.22, publish=publish_obj)

改
基于queryset   返回影响行数
models.Book.objects.filter(pk=1).update(publish_id=3)
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

基于对象  book_obj为该对象
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish_id = 3
book_obj.save()
publish_obj = models.Publish.objects.filter(pk=1).first()
book_obj.publish = publish_obj
book_obj.save()

删
delete  基于queryset  多的一方只是删除该数据   一的一方会将多的一方的关联数据也删除  返回删除的条数(如有外键也会返回外表删除的条数)
models.Book.objects.filter(pk=13).delete()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.delete()

 

 多对多

 # 给书籍绑定与作者之间的关系
    # 添加关系 add:add支持传数字或对象,并且都可以传多个
    # book_obj = models.Book.objects.filter(pk=3).first()
    # # 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=3).first()
    # # book_obj.authors.add(author_obj)
    # book_obj.authors.add(author_obj,author_obj1)

    # 修改书籍与作者的关系  set()  set传的必须是可迭代对象!!!
    # book_obj = models.Book.objects.filter(pk=3).first()
    # 可以传数字和对象,并且支持传多个
    # book_obj.authors.set((1,))
    # book_obj.authors.set((1,2,3))
    #
    # author_list = models.Author.objects.all()
    # book_obj = models.Book.objects.filter(pk=3).first()
    # book_obj.authors.set(author_list)


    # 删除书籍与作者的绑定关系
    # book_obj = models.Book.objects.filter(pk=3).first()
    # # book_obj.authors.remove(1)
    # # book_obj.authors.remove(2,3)
    # # author_obj = models.Author.objects.all().first()
    # author_list = models.Author.objects.all()
    # # book_obj.authors.remove(author_obj)
    # book_obj.authors.remove(*author_list)  # 需要将queryset打散


    # 清空  clear()  清空的是你当前这个表记录对应的绑定关系
    # book_obj = models.Book.objects.filter(pk=3).first()
    # book_obj.authors.clear()


    # 基于对象的表查询
    # 正向
    # 查询书籍是三国演义的出版社邮箱
    # book_obj = models.Book.objects.filter(title=三国演义).first()
    # print(book_obj.publish.email)
    # 查询书籍是金瓶的作者的姓名
    # book_obj = models.Book.objects.filter(title=金瓶).first()
    # print(book_obj.authors)  # app01.Author.None
    # print(book_obj.authors.all())
    # 查询作者为jason电话号码
    # user_obj = models.Author.objects.filter(name=jason).first()
    # print(user_obj.authordetail.phone)

    # 反向
    # 查询出版社是东方出版社出版的书籍                  一对多字段的反向查询
    # publish_obj = models.Publish.objects.filter(name=东方出版社).first()
    # print(publish_obj.book_set)  # app01.Book.None
    # print(publish_obj.book_set.all())

    # 查询作者jason写过的所有的书                      多对多字段的反向查询
    # author_obj = models.Author.objects.filter(name=jason).first()
    # print(author_obj.book_set)  # app01.Book.None
    # print(author_obj.book_set.all())

    # 查询作者电话号码是110的作者姓名                   一对一字段的反向查询
    # authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
    # print(authordetail_obj.author.name)

    # 基于双下滑线的查询
    # 正向
    # 查询书籍为三国演义的出版社地址
    # res = models.Book.objects.filter(title=三国演义).values(publish__addr,title)
    # print(res)
    # 查询书籍为金瓶的作者的姓名
    # res = models.Book.objects.filter(title=金瓶).values("authors__name",title)
    # print(res)
    # 查询作者为jason的家乡
    # res = models.Author.objects.filter(name=jason).values(authordetail__addr)
    # print(res)

    # 反向
    # 查询南方出版社出版的书名
    # res = models.Publish.objects.filter(name=南方出版社).values(book__title)
    # print(res)
    # 查询电话号码为120的作者姓名
    # res = models.AuthorDetail.objects.filter(phone=120).values(author__name)
    # print(res)
    # 查询作者为jason的写的书的名字
    # res = models.Author.objects.filter(name=jason).values(book__title)
    # print(res)
    # 查询书籍为三国演义的作者的电话号码
    # res = models.Book.objects.filter(title=三国演义).values(authors__authordetail__phone)
    # print(res)

    # 查询jason作者的手机号
    # 正向
    # res = models.Author.objects.filter(name=jason).values(authordetail__phone)
    # print(res)
    # 反向
    # res = models.AuthorDetail.objects.filter(author__name=jason).values(phone)
    # print(res)

    # 查询出版社为东方出版社的所有图书的名字和价格
    # 正向
    # res = models.Publish.objects.filter(name=东方出版社).values(book__title,book__price)
    # print(res)
    # 反向
    # res = models.Book.objects.filter(publish__name=东方出版社).values(title,price)
    # print(res)

    # 查询东方出版社出版的价格大于400的书
    # 正向
    # res = models.Publish.objects.filter(name="东方出版社",book__price__gt=400).values(book__title,book__price)
    # print(res)
    # 反向
    # res = models.Book.objects.filter(price__gt=400,publish__name=东方出版社).values(title,price)
    # print(res)



    # 聚合查询  aggregate
    from django.db.models import Max,Min,Count,Sum,Avg
    # 查询所有书籍的作者个数
    # res = models.Book.objects.filter(pk=3).aggregate(count_num=Count(authors))
    # print(res)
    # 查询所有出版社出版的书的平均价格
    # res = models.Publish.objects.aggregate(avg_price=Avg(book__price))
    # print(res)  # 4498.636
    # 统计东方出版社出版的书籍的个数
    # res = models.Publish.objects.filter(name=东方出版社).aggregate(count_num=Count(book__id))
    # print(res)


    # 分组查询(group_by)   annotate
    # 统计每个出版社出版的书的平均价格
    # res = models.Publish.objects.annotate(avg_price=Avg(book__price)).values(name,avg_price)
    # print(res)
    # 统计每一本书的作者个数
    # res = models.Book.objects.annotate(count_num=Count(authors)).values(title,count_num)
    # print(res)
    # 统计出每个出版社卖的最便宜的书的价格
    # res = models.Publish.objects.annotate(min_price=Min(book__price)).values(name,min_price)
    # print(res)
    # 查询每个作者出的书的总价格
    # res = models.Author.objects.annotate(sum_price=Sum(book__price)).values(name,sum_price)
    # print(res)

 

以上是关于Django之Orm操作数据的主要内容,如果未能解决你的问题,请参考以下文章

Django之ORM

Django 基础 之ORM简介与单表操作

九Django之ORM

django之ORM数据库操作

Django之ORM框架的使用

Django学习第5篇:Django之ORM数据库操作