资讯专栏INFORMATION COLUMN

python 入门 django 入门 (二) models操作

e10101 / 1191人阅读

摘要:可通过指明数据库表名。例如查询年添加的品牌查询年月日后添加的品牌比较属性为了方便测试为表添加总数量跟库存为实体类添加字段库存总数量生成迁移文件同步到数据库中查询总数量大于库存的商品中的的聚合函数使用过滤器调用聚合函数。

本人java10年开发经验,现就职于电信,因工作需要学习python,记录自己的学习记录。后面也会持续分享真实工作经验,及项目。欢迎大家互关,一起学习!!文章有不严谨的地方请指出
后面做过项目后,对python有更深的理解了,会录制免费视频,讲解真实项目

1.创建模型类

打开pay应用的models.py创建模型类

from datetime import datetimefrom django.db import models# Create your models here.# 创建品牌的模型类class Brand(models.Model):    # 创建字段,字段类型...    name = models.CharField(max_length=20, verbose_name="名称")    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")    class Meta:        db_table = "brand"  # 指明数据库表名        verbose_name = "分类"  # 在admin站点中显示的名称    def __str__(self):  # self代表当前对象 相当于java的this        """定义每个数据对象的显示信息,相当于java的toString方法"""        return self.name    # 创建商品的模型类class Goods(models.Model):    GENDER_CHOICES = (  # 数据库存储为0跟1 待会查询出来的时候,对象就会替换为后面的value        (0, "上架"),        (1, "下架")    )    name = models.CharField(max_length=20, verbose_name="名称")    status = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name="状态")    description = models.CharField(max_length=200, null=True, verbose_name="描述信息")    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name="品牌")  # 外键    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")    class Meta:        db_table = "goods"        verbose_name = "商品信息"    def __str__(self):        return self.name

修改站点admin.py

from django.contrib import adminfrom .models import Goods, Brand# Register your models here.admin.site.register(Brand)admin.site.register(Goods)

1) 数据库表名

模型类如果未指明表名,Django默认以小写app应用名_小写模型类名为数据库表名。

可通过db_table指明数据库表名。

2) 关于主键

django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。

默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。

生成迁移文件python manage.py makemigrations同步到数据库中python manage.py migrate

创建测试数据:

INSERT INTO brand(NAME,add_time,is_delete) VALUES("手机",NOW(),0),("电脑",NOW(),0),("衣服",NOW(),0),("鞋子",NOW(),0),("生活用品",NOW(),0)INSERT INTO goods(NAME,STATUS,description,is_delete,brand_id)VALUES("华为",0,"华为手机就是牛",0,1),("小米",0,"小米手机天下第一",0,1),("联想",0,"联想",0,1),("七匹狼",0,"七匹狼",0,1),("鬼冢",0,"aaaa",0,1),("拖把",0,"aaaa",0,1)

2.shell工具增删改查

打开pycharm输入

python manage.py shell 

2.1增

create方法也可以增加数据

2.2修改

也可以这样改

2.3删除

2.4查询

get查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。

all查询多个结果。

count统计个数。

mysql的where功能

filter过滤出多个结果exclude排除掉符合条件剩下的结果get过滤单一结果

例如:查询编号为1的品牌

Brand.objects.filter(id__exact=1)   (exact表示相等的意思,两个下划线__)可简写为:Brand.objects.filter(id=1)查询id不为2的记录Brand.objects.exclude(id=2)

mysql中like的功能:

contains:是否包含。 如果要包含%无需转义,直接写即可。

例如:

查询品牌名字中包含"电"的记录Brand.objects.filter(name__contains="电")查询品牌名字中以"电"开头的Brand.objects.filter(name__startwith="电")查询品牌名字中以"脑"结尾的Brand.objects.filter(name__endwith="电")不区分大小写就在前面+i    icontains  istartwith iendwith iexact等

mysql中null的功能

查询品牌名字为null的记录Brand.objects.filter(name__isnull=True)   不为null就是等于false

mysql中in的功能

查询品牌id为2 4 的Brand.objects.filter(id__in=[2,4])

mysql中比较查询

gt大于 (greater then)gte大于等于 (greater then equal)lt小于 (less then)lte小于等于 (less then equal)例如:查询品牌id大于2的记录Brand.objects.filter(id__gt=2)

mysql的日期查询

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。例如:查询2021年添加的品牌Brand.objects.filter(add_time__year="2021")查询2021年10月1日后添加的品牌Brand.objects.filter(add_time__gt="2021-10-01")

2.5比较属性

为了方便测试为goods表添加总数量跟库存

为实体类添加字段quantity = models.IntegerField(default=0, verbose_name="库存")totalCount = models.IntegerField(default=0, verbose_name="总数量")生成迁移文件python manage.py makemigrations同步到数据库中python manage.py migrate

查询总数量大于库存的商品

2.6sql中的and、or

2.7mysql的聚合函数

使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg平均,Count数量,Max最大,Min最小,Sum求和

例如:查询所有商品的总数量

2.8mysql中的排序

2.9关联查询

回顾一下表与表的关系,goods表有外键 brand关联品牌表

from datetime import datetimefrom django.db import models# Create your models here.# 创建品牌的模型类class Brand(models.Model):    # 创建字段,字段类型...    name = models.CharField(max_length=20, verbose_name="名称")    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")    class Meta:        db_table = "brand"  # 指明数据库表名        verbose_name = "分类"  # 在admin站点中显示的名称    def __str__(self):  # self代表当前对象 相当于java的this        """定义每个数据对象的显示信息,相当于java的toString方法"""        return self.name# 创建商品的模型类class Goods(models.Model):    GENDER_CHOICES = (  # 数据库存储为0跟1 待会查询出来的时候,对象就会替换为后面的value        (0, "上架"),        (1, "下架")    )    name = models.CharField(max_length=20, verbose_name="名称")    status = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name="状态")    description = models.CharField(max_length=200, null=True, verbose_name="描述信息")    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name="品牌")  # 外键    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")    quantity = models.IntegerField(default=0, verbose_name="库存")    totalCount = models.IntegerField(default=0, verbose_name="总数量")    class Meta:        db_table = "goods"        verbose_name = "商品信息"    def __str__(self):        return self.name

关联查询例子:

3.其它操作

3.1querySet惰性与查看sql

querySet是惰性操作,只有真正使用时候才会发送sql例如:goods = Goods.objects.all():不会发送sql(注意数据不一致,因为你写这个sql的时候没发出去,用的时候发出去,可能在这期间数据已经改变了)print(goods)才会发送sql可以通过print(goods.query)查看发出的sql语句 帮助调试

3.2get_or_create

直接插入数据可能会冲突Goods.objects.get_or_create(id=20,brand_id=1)  首先尝试获取,不存在就创建,可以防止重复 返回(object, True/False)   true表示创建成功 false表示数据库已经存在该数据类似的还有update_or_create

3.3切片操作

3.4querySet迭代判断

3.5querySet去重distinct

3.6查询某些字段values_list/values

方便查看 修改__str__方法为: def __str__(self):        return "商品名字:%s,描述:%s" % (self.name,self.description)

3.7排除不需要的字段,减少mysqlO

3.8选择需要的字段only

3.9n+1问题

select_related:实用一对一,多对一关系

直接join sql比较简单请自己看

prefetch_related:适用于多对多,一对多情况

是在第一次使用的时候发送

select * from goods where brand_id in(1,2,3,4,5)

因为多对多(比如A表5条对B表5条,join中间表就会是5*5),中间表就会冗余A表每条记录4次 ,而用in的话只需要查B表字段 A表就不会冗余 减少中间表的大小,节约内存

可以加微信群交流学习,相互内推

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123748.html

相关文章

  • 【连载】Django入门到实战(一)

    摘要:一项目目录结构介绍与项目进行交互的命令行工具集的入口项目管理器目录项目容器,包含项目的基本配置,目录名称不建议修改中声明模块的文件,内容默认为空项目的总配置文件,包含数据库应用时间等各种配置配置文件,项目中所有地址页面都需要我们自己去配置其 一、项目目录结构介绍 showImg(https://segmentfault.com/img/remote/1460000016373937?w...

    TwIStOy 评论0 收藏0
  • 【连载】Django入门到实战(一)

    摘要:一项目目录结构介绍与项目进行交互的命令行工具集的入口项目管理器目录项目容器,包含项目的基本配置,目录名称不建议修改中声明模块的文件,内容默认为空项目的总配置文件,包含数据库应用时间等各种配置配置文件,项目中所有地址页面都需要我们自己去配置其 一、项目目录结构介绍 showImg(https://segmentfault.com/img/remote/1460000016373937?w...

    Eastboat 评论0 收藏0
  • 【连载】Django入门到实战(一)

    摘要:一项目目录结构介绍与项目进行交互的命令行工具集的入口项目管理器目录项目容器,包含项目的基本配置,目录名称不建议修改中声明模块的文件,内容默认为空项目的总配置文件,包含数据库应用时间等各种配置配置文件,项目中所有地址页面都需要我们自己去配置其 一、项目目录结构介绍 showImg(https://segmentfault.com/img/remote/1460000016373937?w...

    since1986 评论0 收藏0
  • 【连载】Django入门到实战(一)

    摘要:一项目目录结构介绍与项目进行交互的命令行工具集的入口项目管理器目录项目容器,包含项目的基本配置,目录名称不建议修改中声明模块的文件,内容默认为空项目的总配置文件,包含数据库应用时间等各种配置配置文件,项目中所有地址页面都需要我们自己去配置其 一、项目目录结构介绍 showImg(https://segmentfault.com/img/remote/1460000016373937?w...

    LeexMuller 评论0 收藏0
  • 【连载】Django入门到实战(一)

    摘要:一项目目录结构介绍与项目进行交互的命令行工具集的入口项目管理器目录项目容器,包含项目的基本配置,目录名称不建议修改中声明模块的文件,内容默认为空项目的总配置文件,包含数据库应用时间等各种配置配置文件,项目中所有地址页面都需要我们自己去配置其 一、项目目录结构介绍 showImg(https://segmentfault.com/img/remote/1460000016373937?w...

    bang590 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<