微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python Django 模型层02

一 模型层常用字段和参数

1.模型表建立常用字段

分享图片

1. AutoField:int自增主键列。必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列
 id = models.AutoField(primary_key=True)

2.CharField:字符串,相当于varchar。必须提供max_length参数,不能超过255。
title = models.CharField(max_length=255)

3.IntegerField:整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
kucun = models.IntegerField(null=True) # null参数可不填

4.DecimalField:浮点类型。参数1 max_digits表示总共的位数,参数2 decimal_places表示小数的位数
price = models.DecimalField(max_digits=8,decimal_places=2)

5.DateField:
create_time = models.DateField() # 不指定auto_Now或auto_Now_add时,需要自己传参数 
关键性的参数: 
1.auto_Now:每次操作数据 都会自动刷新当前操作的时间 
2.auto_Now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段
模型表建立常用字段

2.字段参数

分享图片

null
用于表示某个字段可以为空。

unique
如果设置为unique=True 则该字段在此表中必须是唯一的 。

db_index
如果db_index=True 则代表着为此字段设置索引。

default
为该字段设置认值。
字段参数

3.表与表之间的关系字段

https://www.cnblogs.com/tfzz/p/11537119.html

二 设置Django打印sql语句

在settings.py文件中粘贴即可

分享图片

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.大于:__gt 小于:__lt 大于等于:__gte 小于等于:__lte
#价格 大于 小于 大于等于 小于等于
filter(price__gt=90)
filter(price__lt=90)
filter(price_gte=90)
filter(price_lte=90)

2.__in:存在与某几个条件中(相当于或的关系)
filter(price__in=[11,22,33])
models.Tb1.objects.exclude(id__in=[11,22,33])  # not in

3. __range 在某个范围内(顾头又顾尾)
filter(price__range=[50,90])

4. __contains模糊查询
models.Tb1.objects.filter(name__contains="ven")  # 获取name字段包含"ven"的,区分大小写
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不区分

5.__startswith,__istartswith以什么开头(区分大小写和不区分)
6.__endswith,__iendswith以什么结尾(区分大小写和不区分) 

7.date字段可以通过在其后加__year,__month,__day等来获取date的特点部分数据
filter(create_time__year=2017) # 查询2017年的数据
单表双下划线查询

四 多表操作

1.一对多关系 :一对多字段的增删改查

以(Book表 和出版社Publish表为例,一对多关系,为publish外键)为例:

分享图片

from django.db import models
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
示例表

分享图片

1.增: 针对外键关联的字段 两种添加方式
第一种通过 外键字段_id=值
models.Book.objects.create(title=三国演义,price=189.99,publish_id=1)
第二种通过 外键字段=对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title=红楼梦,price=999.99,publish=publish_obj)

2.删
models.Publish.objects.filter(pk=2).delete()  # 认都是级联更新 级联删除

3.改
第一种通过 外键字段_id=值
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)

4.查
.filter()  .all()
一对多字段增删改查

2.多对多关系:多对多字段的 增删改查

以(Book表 和作者Author表为例,多对多关系authors为外键)为例:

注意:对象点击多对多虚拟字段 会直接跨到多对多的第三张表

分享图片

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 Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OnetoOneField(to=AuthorDetail)
示例 

分享图片

1.增:add可以传作者id数字,也可以直接传作者对象,并且支持传多个位置参数(不要混着用)
book_obj = models.Book.objects.filter(pk=1).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=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)

2.删:remove()括号内既可以传数字 也可以传对象,并且支持传对个 逗号隔开即可
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)

3.改:set()括号内 需要传一个可迭代对象 ,可迭代对象中 可以是多个数字组合,也可以是多个对象组合,但是不要混着用!!!
# 将主键为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])

4.查

# 将某本书跟作者的关系全部清空
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.clear()  # 清空当前书籍与作者的所有关系

5.总结:
 """
    add()
    set()
    remove()
    上面三个都支持传数字 或者对象 并且可以传多个 但是set需要传可迭代对象
    
    clear()
    clear括号内不需要传任何参数
    """
多对多字段增删改查

3.正向和反向跨表查询

正向查询:当前表中存在着另一张要查询表的外键,可以通过  .外键  跨表查询称之为正向查询

反向查询当前表中不存在着另一张要查询表的外键,可以通过  .另一张表名  跨查询称之为反向查询

示例表

分享图片

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
示例

#基于对象的正反向查询

正向: 对象.关联字段(外键).字段 /all()

反向: 对象.表名小写(_set).字段/all()

要点:先拿到对象,再通过对象去查对应的外键字段,分两步 

分享图片

正向查询

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)

反向查询

1.查询出版社是东方出版社出版的书籍(一对多) 出版社———》书籍
publish_obj = models.Publish.objects.filter(name=东方出版社).first()
# print(publish_obj.book_set)  # app01.Book.None
print(publish_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)


#正向和反向查询时结果可能为多个时加上 .all(),反向还要表名小写:表名小写_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())
View Code

#基于双下换线的正反向查询

正向:按字段,跨表可以在filter,也可以在values中
反向:按表名小写,也可以在values中

正向:关联字段(外键)__字段

反向:表名小写__字段

分享图片

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)

2.查询手机号是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)

3.查询书籍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)
"""只要表里面有外键字段 你就可以无限制跨多张表"""

4. # 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)
View Code

4.聚合查询(aggregate)

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)

5.分组

    # 分组查询
    # 统计每一本书的作者个数
    from django.db.models import Max,Sum
    # res = models.Book.objects.annotate(author_num = Count(‘authors‘)).values(‘author_num‘,‘title‘) # 依据Book分组,author_num为别名
    # 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)

6.F查询获取字段的值)

#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‘)+‘新款‘) # 不能这么写

7.Q查询(更改条件之间的关系)

  # 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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐