本人java10年开发经验,现就职于电信,因工作需要学习python,记录自己的学习记录。后面也会持续分享真实工作经验,及项目。欢迎大家互关,一起学习!!文章有不严谨的地方请指出 后面做过项目后,对python有更深的理解了,会录制免费视频,讲解真实项目
1.创建模型类
打开pay应用的models.py创建模型类
from datetime import datetime
from django.db import models
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 = '分类'
def __str__(self):
"""定义每个数据对象的显示信息,相当于java的toString方法"""
return self.name
class Goods(models.Model):
GENDER_CHOICES = (
(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 admin
from .models import Goods, Brand
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 datetime
from django.db import models
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 = '分类'
def __str__(self):
"""定义每个数据对象的显示信息,相当于java的toString方法"""
return self.name
class Goods(models.Model):
GENDER_CHOICES = (
(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表就不会冗余 减少中间表的大小,节约内存
可以加微信群交流学习,相互内推
|