一、数据库配置
安装mysql的数据库驱动pysqlclient
pip install mysqlclient
在settings中将DATAVBASES修改为
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db_test', # 数据库名称
'HOST': '127.0.0.1', # 服务器地址
'USER': 'root', # 用户名
'PASSWORD': '123', # 密码
'PORT': 3306 # 端口
}
}
这样我们就连上了我们的数据库。
二、ORM
对象关系映射(Oject Relational Mapping,简称ORM)模式是⼀种为了解决⾯向 对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使⽤描 述对象和数据库之间映射的元数据,⾃动⽣成sql语句,将程序中的对象⾃动保存 到关系数据库中。
优点: 隐藏了数据库访问的细节,简化了sql的使⽤,提⾼了开发效率解耦业务逻辑层(view)和数据处理层(model),简化了开发流程,提⾼了系统的可移植性 提⾼了安全性
缺点: 执⾏效率低对复杂sql⽆能为⼒增加了学习成本
2.1、基本概念
面向对象 | 面向关系 |
---|---|
类 | 表 |
对象 | 记录(一行) |
属性 | 字段(属性、列) |
⼀个模型类对应⼀个表
2.1.1、字段类型
字段名称 | 字段说明 | 参数 |
---|---|---|
AutoField | ⼀个根据实际Id⾃动增⻓的 IntegerField(通常不指定⾃动⽣成) | |
CharField | 字符串,默认的表单样式是 TextInput | max_length=字符⻓度 |
TextField | 大文本字段 | max_digits总位数 decimal_places⼩数位数 |
IntegerField | 整数 | |
DecimalField | 使⽤python的Decimal实例的十进制浮点数 | |
FloatField | 使⽤python的Float实例的十进制浮点数 | |
BooleanField | true/false 字段,此字段的默认 表单控制是CheckboxInput | |
NullBooleanField | 支持null,true,false | |
DateField | 使用python的datetime.date实 例表示的⽇期,该字段默认对 应的表单控件是⼀个TextInput | auto_now和 auto_now_add、 default这三个参数不能共存 |
TimeField | 使⽤Python的datetime.time实 例表示的时间 | 参数同DateField |
DateTimeField | 使⽤Python的 datetime.datetime实例表示的⽇期和时间 | 参数同DateField |
ImageField | 继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image |
2.2.2、字段选项
可选参数 | 说明 |
---|---|
null | 如果True ,Django将 NULL 在数据库中存储空值。默认是 False 。不要在字符串字段上使⽤。null是数据库范畴的概念。 |
blank | 如果 True ,该字段允许为空。默认是False 。同null不同,如果字段有 blank=True ,则表单验证将允许输⼊空值。如果字段有 blank=False ,则需要该字段。 |
db_column | ⽤于此字段的数据库列的名称。如果没有给出,Django将使 ⽤该字段的名称。 |
db_index | 如果True,将为此字段创建数据库常规索引。 |
unique | 如果True,该字段在整个表格中必须是唯⼀的。 |
primary_key | 如果True,此字段是模型的主键。 |
default | 默认值,当前字段如果不给值则执⾏默认值 |
2.2、定义模型
from django.db import models
class 模型名(models.Model):
属性名 = models.字段名(字段选项/参数)
class Meta: #可选,任何⾮字段的设置可以写到Meta中
db_table = 'user' #指定表名为user
如果没有指定主键,Django将⾃动给表创建⼀个自增长主键
id = models.AutoField(primary_key=True)
2.3、激活模型
python manage.py makemigrations #检测App下models.py的变化,记录下变更记录
python manage.py migrate #迁移,将变更记录同步到数据库中
2.4、数据库导入模型
实际上我们经常是先创建数据库再导入模型
python manage.py inspectdb > app/models.py
2.5、一个例子
from django.db import models
class User(models.Model):
# 字段名不能是关键字
# 不能使用连续的下划线
'''
常用字段:
AutoField 一个根据实际id自动增长的integerField整型
CharField 字符串 max_length 规定最大长度
TextField 大文本字段,一般超过4000使用
IntegerField 整型
DecimalField 实数 max_digits规定总位数,decimal_places小数位数
FloatField 浮点数
BooleanField 布尔值 支持Ture False
NullBooleanField 布尔值 支持Ture False Null
DateField 时间值 三个参数auto_now,auto_now_add,default不能共存
TimeField 同DateField
DateTimeField 同DateField
常用参数
null 如果为Ture,则将null在数据库中储存为空
blank 如果为Ture,该字段允许为空
db_column 该字段的名称
unique 如果为Ture,该字段在表中唯一
primary_key 如果为ture,该字段为模型主键
default 默认值 当前字段如果不给值则执行默认值
'''
# 继承自models,确定类型,括号内是限制
uid = models.AutoField(primary_key = True)
# CharField必须指明长度
username = models.CharField(max_length=30,unique=True)
password = models.CharField(max_length=30,unique=True)
regtime = models.DateTimeField(auto_now_add=True)
class Meta: # 元数据,模型本身的信息
# 默认表名 应用名_模型名,这个参数可以修改默认表名
db_table = 'user'
# 当设置成Ture时,这个类不会生成表,而是生成一个抽象类,以供继承
abstract = False
# 排序
ordering = ['username']
三、模型的使用
3.1、增删查改
def sql(request):
# 创建
user = User(username='tom',password='123')
user.save()
# 便利方法创建
user = {'username':'tom','password':'3334'}
User.objects.create(**user)
# 批量创建
User.objects.bulk_create([User(username='em',password='1232312'),User(username='e',password='123')])
# 修改
user = User.objects.get(username='tom')
user.password = '333'
user.save()
# 删除
user = User.objects.get(username='tom')
user.delete()
return HttpResponse("删改")
逻辑删除:不真的删除,但是查询的时候不再查询,增加一个is_delete字段即可实现,一般企业数据都会采取这种删除方法
3.2、Query过滤器
def query(request):
# all过滤器 查询所有数据
users = User.objects.all()
print(users)
# filter过滤器 where
# uid = 5
users = User.objects.filter(uid=316)
print(users)
# uid >= 5
users = User.objects.filter(uid__gt=316)
print(users)
# 可以多次调用 326 >= uid >= 316
users = User.objects.filter(uid__gt=316).filter(uid__lt=326)
print(users)
# 排序 按照username升序排列
data = User.objects.order_by('username')
for user in data:
print(user.username)
# 限制结果集,不能用负下标
# 限制结果集,切片取前两条记录
data = User.objects.order_by('username')[:2]
# 限制结果集,切片取4,5,6,7,8,9条记录
data = User.objects.order_by('uid')[4:9]
# 取指定字段,返回一个字典
data = User.objects.all().values('username')
# 去除重复记录distinct
data = User.objects.all().values('username').distinct()[:10]
# 反序
data = User.objects.order_by('username').reverse()
3.3、字段查询,非过滤器查询
user = User.objects.get(username='tom')
# 返回一个模型对象,最新的一条记录和最后的一条记录
user = User.object.first()
user = User.object.last()
# 查询结果集
num = User.object.filter(uid__lt=10)
# 判断结果集是否为空,返回Ture或者False
flag = User.object.all().exists()
num = User.object.filter(uid__lt=10)
print(flag)
3.4、字段插叙
filter
'''
>= uid__gte=2
> uid__gt=2
< uid__lt=2
<= uid__lte=2
== uid=2
'''
# 集合运算
date = User.object.filter(uid__in=[1,2,3,4])
# 判断空
date = User.object.filter(uid__isnull=Ture)
# 字符串操作
# startswith 以。。开头
# endswith 以。。结尾
date = User.object.filter(username__startswith='张')
date = User.object.filter(username__endswith='张')
# contains 包含
date = User.object.filter(username__contains='张')
# regex 正则匹配
date = User.object.filter(username__regex='^\w+')
# 日期查询
date = User.object.filter(regtime="2020-10-01")
date = User.object.filter(regtime__year=2020)
date = User.object.filter(regtime__month=10)
date = User.object.filter(regtime__day=1)
3.5、统计查询
首先导入一些包
from django.db.models import Max,Min,Avg,Sum,Count
使用,这里以max为例,其他的也一样
def index(request):
uid = User.objects.aggregate(Max('uid'))
print(uid)
uid = User.objects.aggregate(Max('uid')).get('uid__max')
print(uid)
3.6、分组查询
def index(request):
# 分组字段sex 统计字段uid
deta = User.objects.values('sex').annotate(Count('uid'))
print(deta)
# 可以继续过滤
deta = User.objects.values('sex').annotate(Count('uid')).filter(sex=1)
print(deta)
3.7、Q对象和F对象
from django.db.models import Q,F
# Q对象:构造逻辑或逻辑非
# 查询uid>30或者sex=1
deta = User.objects.filter(Q(uid__gt=30)|Q(sex=1))
deta = User.objects.filter(~Q(sex=1))
# F对象 用于比较表中的两个字段
# 把sex堪称User的一个列名,两列值相等的时候输出
date = User.objects.filter(uid=F('sex'))
3.8、原生SQL
tmp = imput('用户名')
user = User.objects.raw(" ")#这个里面写原生的SQL语句
3.9、模型的继承
需要定义,如果父类是抽象的,子类会继承父类所有的表,但如果不是,则不会继承
class Meta:
abstract = Ture
四、字符集
为了能够正常显示中⽂,必须把数据库的字符集设置为utf8
mysql> show variables like 'character%'; #查看字符集
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |需要修改
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |需要修改
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
修改mysql的配置⽂件
cd /etc/mysql/mysql.conf.d
sudo cp mysql.cnf mysql.cnf.bak
sudo vim mysql.cnf
在[mysqld]下增加⼀句:
character_set_server = utf8
保存并重启服务
sudo systemctl restart mysql.service #重启服务