django之模型层(待补充)

模型层

1. ORM查询

所有代码都是在test.py文件中运行的

注意:我如果想在test.py文件中测试相关代码,那么必须要进行配置,不然会报以下的错误

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

意思就是,django本身是一个搭好的框架,你不能单独运行某一个文件,它是一个整体,运行文件前必须要进行环境配置

所以我们的思路就是在test.py文件中,让它一启动改文件,就把相关的环境配置好,于是就加了下面几句

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

## 这几句话的意思就是,启动该文件时,把暴露给用户的配置文件字符串名加到内部环境变量大字典中,然后启动django,就相当于一小型的manage.py启动文件。

查看ORM语句对应的sql语句有两种方式

  1. 如果适合queryset对象,可以直接点query查看
  2. 配置文件中直接配置
LOGGING = {
                'version': 1,
                'disable_existing_loggers': False,
                'handlers': {
                    'console': {
                        'level': 'DEBUG',
                        'class': 'logging.StreamHandler',
                    },
                },
                'loggers': {
                    'django.db.backends': {
                        'handlers': ['console'],
                        'propagate': True,
                        'level': 'DEBUG',
                    },
                }}
## 例1 用query
    from app01 import models
    res = models.Book.objects.all()
    res1 = models.Book.objects.all().query
    print(res)
    print(res1)

#<QuerySet [<Book: 科比自传>, <Book: 艾弗森自传>, <Book: 乔布斯自传>, <Book: 扎克伯格自传>, <Book: 马云自传>]>
#SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`publish_date` FROM `app01_book`

## 例2 用配置文件,直接写一句就可以了。
    res = models.Book.objects.all()

#<QuerySet [<Book: 科比自传>, <Book: 艾弗森自传>, <Book: 乔布斯自传>, <Book: 扎克伯格自传>, <Book: 马云自传>]>
#(0.001) SELECT @@SQL_AUTO_IS_NULL; args=None
#(0.001) SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`publish_date` FROM `app01_book` LIMIT 21; args=()

只要是queryset对象就可以无限制的点queryset对象的方法
queryset.filter().filter().filter(),即使queryset对象是空也没关系

2.单表的增删改操作

## 增

    # 方式一

    models.Book.objects.create(title='时间简史',price=123.23,publish_date='2019-10-24')

'''
这样就会往数据库中存入数据,同时打印出sql语句

INSERT INTO 'app01_book'('title', 'price', 'publish_data') VALUES('时间简史', '123.23', '2019-10-24'); args=['时间简史', '123.23', '2019-10-24']
'''
    # 方式二

    from datetime import date
    ctime = date.today()
    book_obj = models.Book(title='时间简史', price=123, publish_date=ctime)
    book_obj.save()

    #结果和方式一是一样的

## 改

    # 方式一

    models.Book.object.filter(pk=1).update(price=999.66)

    '''
    会把主键为1的数据的价格改为999.66,同时打印出sql语句

    UPDATE 'app01_book' SET 'price'='999.66' WHERE pk=1;
    args=('999.66', 1)
    '''

    # 方式二

    book_obj = models.Book.object.filter(pk=1).first()
    book_obj.title = '奥尼尔自传'
    book_obj.save()

    '''
    打印结果同上,只不过这种效率比较低,会把所有的数据重新保存一遍
    '''

## 删除

    models.Book.object.filter(pk=1).delete()

3. 单表查询(13+__)

13+

## 1.all() 查询所有               QuerySet
    res = models.Book.objects.all() #惰性查询
    print(res)
    for i in res:
        print(i.title)

    '''
    会先把sql语句打印出来

    SELECT 'app01_book'.'id','app01_book'.'title','app01_book'.'price','app01_book'.'publish_date' FROM 'app01_book';

        <QuerySet [<Book: 科比自传>, <Book: 艾弗森自传>, <Book: 乔布斯自传>, <Book: 扎克伯格自传>, <Book: 马云自传>, <Book: 时间简史>]>
    科比自传
    艾弗森自传
    乔布斯自传
    扎克伯格自传
    马云自传
    时间简史

    '''   

## 2.filter()

    res = models.Book.object.filter(pk=2)
    print(res)

    '''
    就相当于语句: select * from book where id = 2
    '''

## 3.get() #不建议使用,这个是数据对象本身

## 4.first() 拿第一个

## 5.last() 拿最后一个
    res = models.Book.objects.all()
    print(res.first())
    print(res.last())

    '''
    sql语句:
        select * from book order by id asc/desc limit 1

    '''

## 6.exclude 除此之外

    #先取出id不是1的所有记录,然后再筛选出id为2的值
    res = models.Book.objects.exclude(pk=1).filter(pk=2)
    print(res)|

    """
    sql语句就是:
        select * from book where (not(id=1) and id=2)
    """

## 7.values 列表套字典

    res = models.Book.objects.values('title')
    for r in res:
        print(r.ger('title'))

    '''
    返回的是一个一个字典,每个字典是title: 书名
    '''

## 8.values_list  列表套元组

    res = models.Book.objects.values_list('title')
    print(res)

    '''
    返回的是一个一个元组,每个元组是 (书名,)
    '''

## 9.count() 统计数据的个数

    res = models.Book.objects.count()
    res1 = models.Book.objects.all().count()
    print(res)
    '''
    返回的是数字,表示有多少个数据,上面两句话是等价的
    '''

## 10.distinct() 去重

    """去重:数据必须是一模一样的情况下才能去重"""
    res = models.Book.objects.all().distinct()
    # 上面这句去不了重,因为id不可能一样,因此需要按照其他的字段先筛选出一批,在进行去重就是避免id的干扰
    res1 = models.Book.objects.values('title', 'price').distinct()
    print(res1)
    '''
    sql语句就是:
        select distinct book.title,book.price from book
    '''

## 11.order_by() 排序

    res = models.Book.objects.order_by('price')  #默认是升序排序
    res1 = models.Book.objects.order_by('-price') #降序排序
    print(res)
    '''
    sql语句就是:
        select * from book order by 'price' asc
    '''

## 12.reverse() 前面必须是先结果排序才可以反转

    res = models.Book.objects.order_by('price').reverse()
    print(res)
    '''
    sql语句就是:
        select * from book order by 'price' desc
    '''

## 13.exists()
    res = models.Book.objects.filter(pk=1).exists()
    print(res)
    '''
    就是判断是否存在这个记录
    '''

双下划线

# __gt/__lt/__gte/__lte=(大于,小于,大于等于,小于等于)

## 查询价格大于200的书籍
res = models.Book.objects.filter(price__get=200)

# __in=[1,2,3] 在列表中就返回,找到一个即可
res = models.Book.objects.filter(price__in=[200, 123.33])

# __range=(200, 700) 顾头不顾尾,在200-700之间
res = models.Book.objects.filter(price__range=(200, 700))

# 模糊匹配

##查询书籍名称中包含p的
res = models.Book.objects.filter(title__contains='p') #区分大小写

res = models.Book.objects.filter(title__icontains='p') #忽略大小写

##以什么开头/结尾  __startswith / __endswith
res = models.Book.objects.filter(title__startswith='三')

##日期
res = models.Book.objects.filter(publish_date__month='10')
res = models.Book.objects.filter(publish_date__year='2019')

多表操作(增删改和简单的查)

### 一对多字段的增删改查

##增

# 直接传出版社主键值
models.Book.objects.create(title='时间简史', price=123.22, publish_id=1)
'''前提是先在出版社中加入id为1的数据,这样就成功插入'''

# 直接传出版社数据对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title="科比自传",price=342.44, publish=publish_obj)

##查

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

多表查询(ORM跨表查询)

#正向查询和反向查询

例如:外键在book表上,book表和publish表是一对多的关系,那么,从book表开始查询,就是正向查询,否则就是反向查询

##记住一句话

    正向查询按字段
    反向查询按表名小写(一对多或者多对多时外键不唯一,这时候就需要 小写表名_set.all())

## 1.子查询

#1.查询时间简史的出版社名字
book_obj = models.Book.objects.filter(title='时间简史').first()
print(book_obj.publish.name)
print(book_obj.publish.addr)
"""正向查询按字段"""

#2.查询书籍主键是7的作者姓名
book_obj = models.Book.objects.filter(pk=7).first()
print(book_obj.authors)  #会打印app01.Author.None  原因是由很多值,但是只接收了一个
"""正确的是""" print(book_obj.authors.all())

#3.查询作者是michael的手机号
author_obj = models.Author.objects.filter(name='michael').first()
print(author_obj.author_detail.phone)

'''
小总结:
    正向查询按字段, 当该字段所对应的数据有多个的时候,加.all() 否则直接点外键字段拿到的是数据对象
'''

#4.查询出版社是人民出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='人民出版社').first()
print(publish_obj.book_set.all())

##5.查询作者是jason写过的所有的书
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set.all())

##6.查询手机号是234的作者
author_detail_obj = models.AuthorDetail.objects.filter(phone=234).first()
print(author_detail.author.name)

'''
小总结:
    反向查找按照表名的小写形式
        加set的时候是一对多或者多对多,主键值不唯一,小写表名_set.all()
        一对一的时候不需要加任何东西,直接点属性
'''

##2.基于双下划线的跨表查询(是按字段查询的,不是按表名)  连表查询
"""
MySQL
    left join
    inner join
    right join
    union
"""

#1.查询书籍是艾弗森自传的出版社名称

#正向
res = models.Book.objects.filter(title="艾弗森自传").values('publish__name')
print(res)
'''
原生sql:
    select publish.name from book inner join publish on (book_id = publish_id) where book.title='艾弗森自传'
'''
#反向
res = models.Publish.objects.filter(book__title='艾弗森自传').values('name')

#2.查询作者是jason的手机号码

#正向
res = models.Author.objects.filter(name='jason').values('author_detail__phone')
print(res)

#反向
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone')

#3.查询手机号是123的作者姓名
##正向
res = models.AuthorDetail.objects.filter(phone=123).values('author__name')

##反向
res = models.Author.objects.filter(author_detail__phone=123).values('name')

#4.查询出版社是东方出版社的书籍名字
#正向
res = models.Publish.objects.filter(name="东方出版社").values('book__title')

#反向
res = models.Book.objects.filter(publish__name='东方出版社').values('title')

#5.查询作者是jason的写过的书的名字和价格
##正向
res = models.Author.objects.filter(name='jason').values('book__title', 'book_price')

##反向
res = models.Book.objects.filter(authors__name='jason').values('title', 'price')
'''反向查找需要到第三张()'''

#6.查询书籍是时间简史的作者的手机号
    res = models.Book.objects.filter(title='时间简史').values('authors__author_detail__phone')
    print(res)

原文地址:https://www.cnblogs.com/michealjy/p/11735647.html

时间: 2024-11-02 13:22:18

django之模型层(待补充)的相关文章

Django框架-模型层

Django框架-模型层 一.单表查询之必知必会13条 1.时间字段中的两个关键性参数 create_time = models.DateField() # 年月日 create_time = models.DateTimeField() # 年月日时分秒 # 两个关键性参数 # auto_now:每次操作数据 都会自动刷新当前操作的时间 # auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段 2.搭建测试环境 在django中,你可以写一个单独测试某

Django之模型层第二篇:多表操作

Django之模型层第二篇:多表操作 一 表关系回顾 ? 在讲解MySQL时,我们提到,把应用程序的所有数据都放在一张表里是极不合理的. ? 比如我们开发一个员工管理系统,在数据库里只创建一张员工信息表,该表有四个字段:工号.姓名.部门名.部门职能描述,此时若公司有1万名员工,但只有3个部门,因为每一名员工后都需要跟着部门信息(部门名.部门职能),所以将会导致部门信息出现大量重复.浪费空间. ? 解决方法就是将数据存放于不同的表中,然后基于foreign key建立表之间的关联关系. ? 细说的

Django的模型层

Django模型层是Django框架自己定义的一套独特的ORM技术.使用django模型开发的首要任务就是定义模型类及其属性.每个模型类都可以被映射为数据库中的一个数据表,而类属性被映射数据字段,除此之外,数据库表的主键.外键.约束等也通过类属性完成定义. 1.模型定义,通过模型类中的Mata子类定义数据模型,比如数据库的表名.数据默认排序方式等. 2.普通字段类型,普通字段类型指模型类中除了外键关系外的数据字段属性. 3.常用字段参数,每个字段类型都有一些特定的HTML标签和表单验证参数, 4

Django之模型层&amp;ORM操作

一. 单表查询:  1.在模型层创建模型表: from django.db import models # Create your models here. # 单表查询表 class User(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() register_time = models.DateField()      2.连接MySQL,创建表 (具体操作见https://ww

4.Django|ORM模型层

ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动 ORM是"对象-关系-映射"的简称. 不需要调用sqmysql,django的上层封装:它只能做到表这一层 1 #sql中的表 2 3 #创建表: 4 CREATE TABLE employee( 5 id INT PRIMARY KEY a

Django之模型层-多表操作

多表操作 数据库表关系 一对多:两个表之间的关系一旦确定为一对多,必须在数据多的表中创建关联字段 多对多:两个表之间的关系一定确定为多对多,必须创建第三张表(关联表) 一对一:一旦两个表之间的关系确定为一对一,在两种表中任意一张表中建立关联字段unique ORM生成关联表模型 class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32) pric

Django框架(模型层:单表查询)

创建表 1.创建模型 创建名为book的app,在book下的models.py中创建模型 from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=64) pub_data = models.DateField() price = model

django之模型层

1. ORM MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动 ORM是"对象-关系-映射"的简称. Mysql #sql中的表 #创建表: CREATE TABLE employee( id INT PRIMARY KEY auto_increment , name VARCHAR (20), gen

Django 09-1模型层 查询(分组、聚合)

Django 查询(分组.聚合) 一.聚合查询 # 聚合函数的使用场景 -- 单独使用:不分组,只查聚合结果 -- 分组使用:按字段分组,可查分组字段与聚合结果 # 导入聚合函数 from django.db.models import Avg, Max, Min, Count, Sum 单独聚合查询:aggregate(*args,**kwargs) # 语法: aggregate(别名=聚合函数('字段')) # 规则: 1.可以同时对多个字段进行聚合处理:aggregate(别名1=聚合函