Python系列之Django(ORM)

ORM

基础操作

  • 链接mysql数据库

    setting.py中修改数据库配置文件,本教程咱们以MySQL为例

        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'orm',           # 要连接的数据库,连接前需要创建好
            'USER': 'docker',        # 连接数据库的用户名
            'PASSWORD': 'docker',    # 连接数据库的密码
            'HOST': '127.0.0.1',     # 连接主机,默认本级
            'PORT': 3306             #  端口 默认3306
        }

    因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的init,在里面写入:

        import pymysql
        pymysql.install_as_MySQLdb()

    最后通过两条数据库迁移命令即可在指定的数据库中创建表 :

        python manage.py makemigrations
        python manage.py migrate
  • 小技巧:如果想打印orm转换过程中的sql,需要在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',
            },
        }
    }

数据表

利用Djangoorm创建数据表,不能创建数据库,用因为Django是基于数据表的,不是基于数据库的。

创建数据表

我们一般在对应模块下的model.py中创建数据表

简单实例:

class Book(models.Model):
    '''
    创建Book数据表
    '''
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    press = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    anther = models.CharField(max_length=11)

然后执行数据库迁移即可。

添加数据

方式一:

    res = models.Book.objects.create(
        name        ="GO宝典",
        press       ="南京出版社",
        price       =1220.3,
        anther      ="Jack"
    )

方式二:

    res = Book(
        name        ="LINUX宝典",
        press       ="河南出版社",
        price       =10.3,
        anther      ="Mosson",
        text        ="String",
        email       ="[email protected]"
    )

    res.save()

查询

基础查询

  • all(): 查询所有结果
  • filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
  • get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
  • exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
  • order_by(*field): 对查询结果排序
  • reverse(): 对查询结果反向排序
  • count(): 返回数据库中匹配查询(QuerySet)的对象数量。
  • first(): 返回第一条记录
  • last(): 返回最后一条记录
  • exists(): 如果QuerySet包含数据,就返回True,否则返回False
  • values 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列(在QuertSet中存放字典序列)
Book.objects.all().values("title")
  • values_list() 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列(在QuertSet中存放元组序列)
Book.objects.all().values_list("title")
  • distinct 从返回结果中剔除重复纪录(配合values和values_list使用)
Book.objects.all().distinct()

基于双下划线的模糊查询 

Book.objects.filter(price__gt=10, price__lt=20)
  • 双下划线的查询列表
__gt : 大于
__lt : 小于
__startswith : 以xxx开头
__in : 在xxx之中
__contains : 包含(区分大小写)
__icontains : 包含(不区分大小写)
__range : 范围

删除

  • 删除所有(无返回值)
model_obj.delete()
  • 条件删除(返回删除的ID)
Book.objects.all().values("title").delete()

修改

  • 条件修改
models.Book.objects.filter(price__gt=1000).update(name="PHP")

多表操作

创建数据

    publish_v1 = Publish.objects.get(nid=1)
    publish_v2 = Publish.objects.get(nid=2)
    publish_v3 = Publish.objects.get(nid=3)

    res = Book.objects.create(
        title       = "MacBook Pro",
        publishDate = "2018-09-18",
        price       = 12.34
    )

    res.publish.add(publish_v1, publish_v2, publish_v3)

删除数据

    res = Book.objects.get(nid=11).delete()

查询

  • 一对多(正向查询):
    # 查询主键为1的书籍的出版社所在的城市
    book_obj=Book.objects.filter(pk=1).first()
    # book_obj.publish 是主键为1的书籍对象关联的出版社对象
    print(book_obj.publish.city)  
  • 一对多(反向查询):
    res = Publish.objects.get(name="北京出版社").book_set.get(nid=12)
  • 一对一(正向查询):
    res = Author.objects.filter(name="Alvin").first().antherDetail.telephone
  • 一对一(反向查询):
    res = AuthorDetail.objects.filter(telephone=16621068505)
    for obj in res:
        print(obj.author.name)
  • 多对多(正向查询):
    res = Book.objects.filter(title="PHP").first().anther.all()
    for obj in res:
        print(obj.name)
  • 多对多(反向查询):
    res = Author.objects.filter(name="Alvin").first().book_set.all()
    for i in res:
        print(i.title)

基于双下划线的跨表查询

  • 一对多(正向查询)
    res = Book.objects.filter(publish__name="北京出版社").all()
  • 一对多(反向查询)
    res = Publish.objects.filter(name="北京出版社").values_list("book__title")
  • 多对多(正向查询):
    res = Book.objects.filter(title="PHP").values_list("anther__name")
  • 多对多(反向查询):
    res = Author.objects.filter(name="Alvin").values_list("book__title")
  • 一对一(正向查询):
    res = Author.objects.filter(name="Alvin").values_list("antherDetail__addr")
  • 一对一(反向查询):

    res = AuthorDetail.objects.filter(author__age=23).values_list("author__name")

注:反向查询时,如果定义了related_name ,则用related_name替换表名

聚合查询与分组查询

聚合(aggregate)

    res = Book.objects.filter(title="PHP").aggregate(Avg("price"))

分组(annotate)

    res = Book.objects.values("price").annotate(c=Count("*"))

附:

from django.db import models
# Create your models here.

class Book(models.Model):
    '''
    Book数据表
    '''
    nid         = models.AutoField(primary_key=True)
    title       = models.CharField( max_length=32)
    publishDate = models.DateField()
    price       = models.DecimalField(max_digits=5,decimal_places=2)

    # 与出版社表建立一对多的关系
    publish = models.ManyToManyField(to="Publish",)

    # 与Auther建立多对多的关系
    anther = models.ManyToManyField(to="Author",)

class Author(models.Model):
    '''
    Auther表
    '''
    nid     = models.AutoField(primary_key=True)
    name    = models.CharField( max_length=32)
    age     = models.IntegerField()

    # 与作者详情表建立一对一的关系
    antherDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)

class AuthorDetail(models.Model):
    '''
    作者详情表
    '''
    nid         = models.AutoField(primary_key=True)
    birthday    = models.DateField()
    telephone   = models.BigIntegerField()
    addr        = models.CharField( max_length=64)

class Publish(models.Model):
    '''
    出版社表
    '''
    nid     = models.AutoField(primary_key=True)
    name    = models.CharField( max_length=32)
    city    = models.CharField( max_length=32)
    email   = models.EmailField()

你可能感兴趣的:(python,Django)