ORM表单操作

准备工作:

  1、在orm操作表单之前需要先修改下django中连接的数据库,默认连接的是SQLit3,这里我们修改成mysql

  2、mysql使用的版本是5.6,已经安装好了,直接连接就可以使用

创建django项目,这里我创建的django使用的是pycharm创建的,其中应用、模板都已经创建好了,不需要我们手动去创建了,因为要连接到mysql数据库,默认不支持mysql连接,我们还需要做一些修改。

  创建需要用到的数据库库文件:

  库名:book_system

  修改django中配置文件settings.py文件:

    

在项目中或者应用中目录的__init__.py文件中添加

import pymysql
pymysql.install_as_MySQLdb()

  到这里初步的设置算是完成了,因为我们要使用orm操作数据库,还需要先设计表格字段类型

  在创建的应用app中的models.py目录中创建类

 

class User(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    # DateField  年月日;DateTimeField  年月日时分秒
    register_time=models.DateField()
    def __str__(self):
        return '对象的名字是:%s'%self.name
# 设计book表
class Book(models.Model):
    # 设置title字段为varchar类型
    title=models.CharField(max_length=32)
    # max_digists设置数字长度最大为8,decimal_places小数位
    price=models.DecimalField(max_digits=8,decimal_places=2)
    # DateField  年月日;DateTimeField  年月日时分秒;auto_now:每次操作改数据都会自动更新时间;auto_now_add:新增数据的时候会将当前时间自动添加,后续的修改该字段不会自动更新
    publish_date=models.DateField(auto_now_add=True)
    # 外键关系
    publish=models.ForeignKey(to='Publish')
    authors=models.ManyToManyField(to='Author')

    def __str__(self):
        return '书籍对象的名字是:%s'%self.title

# 设计出版社表
class Publish(models.Model):
    name=models.CharField(max_length=32)
    addr=models.CharField(max_length=32)
    #这里默认EmailField类型在不加载其它模块的情况下就是char类型
    email=models.EmailField()
    def __str__(self):
        return '出版社对象的名字:%s'%self.name
# 设计作者表格
class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()

    authordetail=models.OneToOneField(to='AuthorDetail')
    def __str__(self):
        return '作者对象的名字:%s'%self.name

#作者表的扩展表
class AuthorDetail(models.Model):
    phone=models.CharField(max_length=32)
    addr=models.CharField(max_length=32)

  执行数据库迁移命令、生成数据库需要的表   

  python3 manage.py makemigrations 将数据库更改记录添加到小本本上(对应应用下migrations文件夹)
  python3 manage.py migrate 将更改同步到数据库(真正的操作数据库)

  执行完成后查看数据:

有一些是我们自己设计的,有些是orm系统自己需要用到的表

注意:数据库创建好了,单独的py文件测试orm操作会报错,需要配置参

导入app应用中的models模块

  • 一、数据操作从创建、删除、修改、查询这四个方面开始

新增数据的两种方式:

新增数据方式1:(基于create方法创建)

    #新增数据,创建表
    user_obj=models.User.objects.create(name='jason',age='25',register_time='2019-06-12')
    print(user_obj.register_time)

 

新增数据方式2:(基于对象绑定的方法创建)

from django.test import TestCase

# Create your tests here.
import os
import sys
import datetime

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test01.settings")
    import django
    django.setup()
    from app01 import models
    #新增数据,创建表
    # user_obj=models.User.objects.create(name='jason',age='25',register_time='2019-06-12')
    # print(user_obj.register_time)

    user_obj=models.User(name='tank',age='23',register_time=datetime.datetime.now())
    user_obj.save()

删除数据的两种方式

 

# 方式1
res = models.User.objects.filter(name='tank').delete() print(res)  #删除数据会有返回值
# 方式2
res = models.User.objects.filter(name='jason').first()
res.delete()  #删除数据没有返回值

修改数据两种方式

 

# 方式1
models.User.objects.filter(name='tank').update(age='18')
# 方式2
res=models.User.objects.filter(name='tank').first()
res.age=20
res.save()

 

查询数据

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

    res=models.User.objects.all()
    print(res)

    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
res = models.User.objects.filter(name='tank',age=21) print(res) #filter内支持多个参数,查询条件只有同时满足才会返回查询结果 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 res =models.User.objects.exclude(name='tank') print(res) #查询返回exclude条件之外的其它数据,通俗点就是取反 <5> order_by(*field): 对查询结果排序('-id')/('price')
  res=models.User.objects.order_by('name')
  print(res)  #order_by内可以不同的字段
  res=models.User.objects.order_by('-name')
  print(res)  #倒叙,效果和reverse一样
    <6> reverse():              对查询结果反向排序 	>>>前面要先有排序才能反向

    <7> count():                返回数据库中匹配查询(QuerySet)的对象数量。
  res=models.User.objects.count()
  print(res)

<8> first(): 返回第一条记录
  res=models.User.objects.all().first()
  print(res)

<9> last(): 返回最后一条记录
  
  res=models.User.objects.all().last()
  print(res)
<10> exists(): 如果QuerySet包含数据,就返回True,否则返回False 
res=models.User.objects.filter(name='test').exists()
print(res) #判断数据是否存在,存放返回true,不存在返回false


<11> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列


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

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

基于双下划线的查询

res=models.User.objects.filter(age__gt=21)
print(res)  # 查询年龄大于21岁

res=models.User.objects.filter(age__lt=21)
print(res)  # 查询年龄小于21岁

   

age__gte  #大于等于
age__lte  #小于等于 
age__in=[44,22,73]  #年龄是44或22或73,只要有一个满足就返回数据

age__range=[22,44]  #年龄在22——44之间范围内

register_time__year=2019  #register_time这个字段的日期数据中年份是2019的数据打印出来

res=models.User.objects.filter(name__contains='o')
print(res)  #name字段中包含有o字符的值打印出来
name__icontains='E'  #含有E字符的值都打印出来,不区分大小写

name__startswith='t'  #字段中符合指定字符开头的打印出来
name__endswith='n'  #字段中负责指定字符结尾的打印出来

到此单表查询结束
=================================================================

多表查询

  插入数据
  
models.Book.objects.create(title='红楼梦',price='66.66',publish_id=1)
  传输数据对象:
  
publish_obj=models.Publish.objects.filter(pk=2).first()
  models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)
  修改数据
  
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)
  对象修改

    book_obj = models.Book.objects.filter(pk=1).first()

   book_obj.publish_id = 3 # 点表中真实存在的字段名

  book_obj.save()

  

  publish_obj = models.Publish.objects.filter(pk=2).first()
  book_obj.publish = publish_obj  # 点orm中字段名 传该字段对应的表的数据对象
  book_obj.save()
  
  删除数据
  
models.Book.objects.filter(pk=1).delete()
  models.Publish.objects.filter(pk=1).delete()
 
  book_obj = models.Book.objects.filter(pk=3).first()
  book_obj.delete()
 多表之间添加关系(数据)
  方法1
  book_obj = models.Book.objects.filter(pk=3).first()
 book_obj.authors.add(1)

   方法2
  author_obj = models.Author.objects.filter(pk=1).first()
  author_obj1 = models.Author.objects.filter(pk=3).first()
  book_obj.authors.add(author_obj,author_obj1)

  修改表关系使用set(),set传递的必须是可迭代对象

   方法1

   book_obj = models.Book.objects.filter(pk=3).first()

   可以传数字和对象,并且支持传多个

  book_obj.authors.set((1,))
  book_obj.authors.set((1,2,3))

  方法2
  
author_list = models.Author.objects.all()
  book_obj = models.Book.objects.filter(pk=3).first()
  book_obj.authors.set(author_list)

删除书籍与作者的绑定关系
  方法1
  
book_obj = models.Book.objects.filter(pk=3).first()
  book_obj.authors.remove(1)


  方法2
  book_obj = models.Book.objects.filter(pk=3).first()
  author_list = models.Author.objects.all()
  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())
    查询作者为‘大猫’的电话号码
    phone_obj=models.Author.objects.filter(name='大猫').first()
    print(phone_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)
    查询书籍为xxx的作者的姓名
    res = models.Book.objects.filter(title='xxx').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)
聚合查询  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)



posted @ 2019-06-13 00:24  阳光与叶子  阅读(273)  评论(0编辑  收藏  举报