模型层

查看orm内部sql语句的方法的方法

  1.如果是queryset对象,那么可以点query直接查看该queryset的内部sql语句

  2.在Django项目的配置文件中,配置一下参数即可实现所有的orm在查询的时候自动打印对应的sql语句

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

models.py

from django.db import models

# Create your models here.
class Book(models.Model):
title = models.CharField(max_length=255)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField(auto_now_add=True) # 库存数 后加的,需要手动传值
kucun = models.IntegerField(null=True)
# 卖出数 后加的,需要手动传值
maichu = models.IntegerField(null=True) publish = models.ForeignKey(to='Publish') # 默认是跟publish的主键字段做的一对多外键关联
authors = models.ManyToManyField(to='Author')
# 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 def __str__(self):
return self.title class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
# email = models.EmailField() # 就是varchar(254) def __str__(self):
return self.name class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail') def __str__(self):
return self.name
class AuthorDetail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=64)
"""
models.py中的模型类__str__方法 必须返回一个字符串形式数据!!! """
def __str__(self):
return self.addr

基于models.py中表的查询方法(补充Q的高级用法末尾)

from django.test import TestCase

# Create your tests here.
import os if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day55.settings")
import django
django.setup()
"""在下面就可以写针对某一个py文件的测试代码"""
from app01 import models
# 一对多的字段的增删改查
# 增
# publish_id传数字
# models.Book.objects.create(title='三国演义',price=189.99,publish_id=1)
# publish直接传出版社对象
# publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='红楼梦',price=999.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) # 查 # 删
# models.Publish.objects.filter(pk=2).delete() # 默认都是级联更新 级联删除 # 多对多字段的增删改查
# 增
# 要给主键为1的书籍添加两个作者
# book_obj = models.Book.objects.filter(pk=1).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()
# author_obj2 = models.Author.objects.filter(pk=3).first()
# book_obj.authors.add(author_obj)
# book_obj.authors.add(author_obj1,author_obj2)
"""
add()
是给书籍添加作者 括号内既可以传数字也可以传对象
并且支持一次性传多个 逗号隔开即可
""" # 改
# 将主键为1的书籍对象 作者修改为2,3
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.set([2,])
# book_obj.authors.set([2,3]) # author_obj = models.Author.objects.filter(pk=1).first()
# author_obj1 = models.Author.objects.filter(pk=2).first()
# author_obj2 = models.Author.objects.filter(pk=3).first()
# book_obj.authors.set([author_obj,])
# book_obj.authors.set([author_obj, author_obj1, author_obj2])
"""
set()括号内 需要传一个可迭代对象
可迭代对象中 可以是多个数字组合
也可以是多个对象组合
但是不要混着用!!!
""" # 删
# book_obj = models.Book.objects.filter(pk=1).first()
# # book_obj.authors.remove(3)
# book_obj.authors.remove(1,2)
# author_obj = models.Author.objects.filter(pk=1).first()
# author_obj1 = models.Author.objects.filter(pk=2).first()
# author_obj2 = models.Author.objects.filter(pk=3).first()
# book_obj.authors.remove(author_obj)
# book_obj.authors.remove(author_obj1,author_obj2)
"""
remove()括号内既可以传数字 也可以传对象
并且支持传对个 逗号隔开即可
""" # 将某本书跟作者的关系全部清空
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.clear() # 清空当前书籍与作者的所有关系 """
add()
set()
remove()
上面三个都支持传数字 或者对象 并且可以传多个 但是set需要传可迭代对象 clear()
clear括号内不需要传任何参数
""" # 跨表查询(******)
"""
正向与反向的概念 # 一对一
# 正向:author---关联字段在author表里--->authordetail 按字段
# 反向:authordetail---关联字段在author表里--->author 按表名小写 # 一对多
# 正向:book---关联字段在book表里--->publish 按字段
# 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书 # 多对多
# 正向:book---关联字段在book表里--->author 按字段
# 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书 正向查询按外键字段
反向查询按表名小写
"""
"""基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)"""
"""
强调:在书写orm语句的时候 跟写sql语句一样
不要尝试着 一次性写完 应该做到写一点看一点再一点
"""
# 1.查询书籍id是1 的出版社名称
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.publish.name)
# print(book_obj.publish.addr) # 2.查询书籍id是2 的作者姓名
# book_obj = models.Book.objects.filter(pk=2).first()
# print(book_obj.authors) # app01.Author.None
# print(book_obj.authors.all())
# res = book_obj.authors.all()
# for r in res:
# print(r.name) # 3.查询作者是jason的家庭住址
# author_obj = models.Author.objects.filter(name='jason').first()
# print(author_obj.author_detail.addr) # 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.查询电话号码是130的作者姓名
# author_detail_obj = models.AuthorDetail.objects.filter(phone=130).first()
# print(author_detail_obj.author.name)
# print(author_detail_obj.author.age)
"""
当你反向查询的结果是多个的时候 就需要加_set
否则直接表明小写即可
""" # 7.查询书籍id为1 的作者的电话号码
# book_obj = models.Book.objects.filter(pk=1).first()
# author_list = book_obj.authors.all()
# for author_obj in author_list:
# print(author_obj.author_detail.phone) """基于双下划綫的跨表查询(连表操作)
left join
inner join
right join
union
"""
# 正向
# 1.查询jason作者的手机号
# res = models.Author.objects.filter(name='jason').values('author_detail__phone','author_detail__addr')
# print(res) # res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
# print(res1) # 查询jason这个作者的年龄和手机号
# 正向
# res = models.Author.objects.filter(name='jason').values('age','author_detail__phone')
# print(res)
# 反向
# res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age')
# print(res1) # 查询手机号是130的作者年龄
# 正向
# res = models.AuthorDetail.objects.filter(phone=130).values('author__age')
# print(res)
# # 反向
# res1 = models.Author.objects.filter(author_detail__phone=130).values('age')
# print(res1) # 查询书籍id是1 的作者的电话号码
# res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
# res1 = models.Book.objects.filter(pk=1).values('外键字段1__外键字段2__外键字段3__普通字段')
# print(res)
"""只要表里面有外键字段 你就可以无限制跨多张表""" # 1.查询出版社为北方出版社的所有图书的名字和价格
# res = models.Publish.objects.filter(name='北方出版社').values('book__title','book__price')
# print(res) # 2.查询北方出版社出版的价格大于19的书
# res = models.Book.objects.filter(price__gt=19,publish__name='北方出版社').values('title','publish__name')
# print(res) # 聚合查询(aggregate)
# 1.统计所有书的总价格
# from django.db.models import Max,Min,Count,Avg,Sum
#
# # res = models.Book.objects.aggregate(Sum('price'))
# res1 = models.Book.objects.aggregate(Avg('price'))
# res2 = models.Book.objects.aggregate(Count('price'))
# res3 = models.Book.objects.aggregate(Max('price'))
# res4 = models.Book.objects.aggregate(Min('price'))
# res5 = models.Book.objects.aggregate(Max('price'),Min('price'),Count('pk'),Avg('price'),Sum('price'))
# print(res5)
# print(res)
# print(res1)
# print(res2) # 分组查询
# 统计每一本书的作者个数
from django.db.models import Max, Min, Count, Avg, Sum
# res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','title')
# print(res) # 统计出每个出版社卖的最便宜的书的价格
# res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')
# print(res) # 统计不止一个作者的图书
# res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
# print(res) """
只要是queryset对象 就可以无限制的调用queryset对象的方法!!!
最最常用的就是对一个已经filter过滤完的数据 再进行更细化的筛选 """ # 查询各个作者出的书的总价格
# res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp')
# print(res) #F查询的本质就是从数据库中获取某个字段的值
# 查询库存数大于卖出数的书籍
"""之前查询等号后面的条件都是我们认为输入的
现在变成了需要从数据库中获取数据放在等号后面
"""
from django.db.models import F
# res = models.Book.objects.filter(kucun__gt=F('maichu'))
# print(res) # 将书籍库存数全部增加1000
# models.Book.objects.update(kucun=F('kucun')+1000) # 把所有书名后面加上'新款' # from django.db.models.functions import Concat
# from django.db.models import Value
#
# ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
# models.Book.objects.update(title = F('title')+'新款') # 不能这么写 # Q查询
from django.db.models import Q
# 查询书籍名称是三国演义或者价格是444.44
# res = models.Book.objects.filter(title='三国演义',price=444.44) # filter只支持and关系
# res1 = models.Book.objects.filter(Q(title='三国演义'),Q(price=444)) # 如果用逗号 那么还是and关系
# res2 = models.Book.objects.filter(Q(title='三国演义')|Q(price=444))
# res3 = models.Book.objects.filter(~Q(title='三国演义')|Q(price=444))
# print(res2) # Q高级用法
q = Q()
q.connector = 'or' # 修改查询条件的关系 默认是and
q.children.append(('title__contains','三国演义')) # 往列表中添加筛选条件
q.children.append(('price__gt',444)) # 往列表中添加筛选条件
res = models.Book.objects.filter(q) # filter支持你直接传q对象 但是默认还是and关系
print(res)

自定义char字段

    class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs)
self.max_length = max_length
super().__init__(max_length=max_length,*args,**kwargs) def db_type(self,connection):
return 'char(%s)'%self.max_length class User(models.Model):
username = MyCharField(max_length=32)

Django学习之模型层的更多相关文章

  1. Django的日常-模型层(1)

    目录 Django的日常-模型层(1) 模型层 django测试环境 ORM查询 Django的日常-模型层(1) 模型层 模型层其实就是我们应用名下的models.py文件,我们在里面写入想要创建的 ...

  2. Django的日常-模型层(2)

    目录 Django的日常-模型层(2) 几种常用的查询方式 聚合查询 分组查询 F和Q查询 查询优化相关 orm中常见字段 choices参数 orm的事务操作 Django的日常-模型层(2) 几种 ...

  3. Django基础之模型层(02)

    1 重要概念 # 多表查询 """ 正向查询 反向查询 当前查询对象是否含有外键字段 如果有就是正向 没有无则是反向 口诀: 正向查询按外键字段 多对多需要额外再加一个. ...

  4. Django基础(3)----模型层-单表操作,多表创建

    昨日内容回顾: 1. {% include '' %} 2. extend base.html: <html> ..... ..... ..... {% block content%} { ...

  5. django学习笔记-模板层

    模板层 将Python嵌入到HTML中. 模板简介 将HTML硬解码到视图并不是那么完美原因如下: 对页面设计时也需要对python代码进行相应的修改,模板可以不就行python代码修改的情况下变更设 ...

  6. Django 学习 之路由层(URL)

    路由层(URL) 1.路由层简单配置 (1)path方法 写固定的url. (2)re_path方法 可以正则规则 例: urlpatterns = [ path('admin/', admin.si ...

  7. Django学习之模板层

    三板斧 render,HttpResponse,redirectrender返回一个HTML页面,并且还能够给该页面传数据render内部原理: from django.template import ...

  8. Django学习之路由层

    Django请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校验或在请 ...

  9. django 学习-7 模型数据操作

    1.首先还是创建办一个项目和一个应用 django.admin.py   startproject    ssj cd  ssj django.admin.py   startapp    sdj 那 ...

随机推荐

  1. PyGame快速入门

    pygame 快速入门 目标 项目准备 使用 pygame 创建图形窗口 理解 图像 并实现图像绘制 理解 游戏循环 和 游戏时钟 理解 精灵 和 精灵组 项目准备 新建 飞机大战 项目 新建一个 h ...

  2. 因子分析和PCA总结

    因子分析和PCA 定义 因子分析就是数据降维工具.从一组相关变量中删除冗余或重复,把相关的变量放在一个因子中,实在不相关的因子有可能被删掉.用一组较小的“派生”变量表示相关变量,这个派生就是新的因子. ...

  3. css实现高度自适应

    要求.上部固定高度50px,下部分自适应剩下整个屏幕 html, body { height: 100%; margin: 0px; padding: 0px; } #main { backgroun ...

  4. vue项目起步准备

    1. 项目环境: node.js运行环境(不一定要最新特性的最新版本,用合适的版本即可) 2.项目放在git上管理(网上云仓库码云) 1.创建仓库:选择语言js 2.本地代码和线上代码通过git做成关 ...

  5. CSS——fixed 固定定位相对于父容器

    position:fixed 固定定位 用 left top 都是相对于浏览器的. 我今天想给网页做一个固定定位的导航 偶然间发现.可以用margin 相对于父容器定位. 小伙伴们可以试试. 不用le ...

  6. 使用idea出现的错误

    错误:打开maven项目时出现"程序包 com.sun.org.apache.xpath.internal 不可见 "的错误 这个问题出现的原因是: jdk版本的问题.可能是因为有 ...

  7. MYSQL8用户创建及权限操作

    MYSQL8创建.删除用户和授权.消权操作 上网找过资料说要进入mysql数据库在进行这些操作,我试了发现不进数据库和进入mysql数据库效果都一样 网上有的直接创建并赋权,像酱紫的: grant a ...

  8. Dynamics CRM - 不同类型字段在 Plugin 里的赋值方式

    在编写 Plugin 代码之前,我们可以需要用 SDK bin 目录下的 CrmSvcUtil.exe 来将 CRM Site 上所有的 Entity 转换成类,而 Entity 里的 Field 也 ...

  9. dbus探索

    一.参考网址 1.Dbus组成和原理

  10. python3 str.encode bytes.decode

    str.encode 把字符串编码成字节序列 bytes.decode 把字节序列解码成字符串 https://docs.python.org/3.5/library/stdtypes.html st ...