前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django篇(二)

Django篇(二)

作者头像
不断折腾
发布2019-09-23 10:55:08
1.3K0
发布2019-09-23 10:55:08
举报

配置使用mysql数据库

之前我们使用的是Django中自带的数据库sqlite数据库。

这篇文章让我们切换成mysql,不会MySQL基础的可以去查询数据库篇的文章。

1、创建项目

2、创建应用

3、注册应用

4、修改setting.py来让我们的Django框架支持mysql数据库。

在setting.py找到DATABASES,修改成:

DATABASES = {

'default': {

'ENGINE':'django.db.backends.mysql',

'NAME':'student',

'USER':'root',

'PASSWORD':'123456',

'HOST':'localhost',

'PORT':3306,

}

}

ENGINE:选择数据库

NAME:数据库的名字

USER:登陆账号

PASSWORD:密码

HOST:本地填写localhost,不是就写ip地址

PORT:3306.

5、我们还需要安装操作mysql的模块

在虚拟环境中pip instal pymysql

6、在test3下的test3下的__init__添加:

import pymysql

pymysql.install_as_MySQLdb()

此时我们运行项目就不会有问题了。

常见模型字段属性

模型属性命名:

1、不能是python保留关键字

2、不允许出现联系的下划线

字段类型

第一篇文章中我们仅仅了解了几个。

接下来我们重新了解一下有什么其他模型。

首先在使用时,我们需要导入django.db.models包

AutoField:

自动增长的IntegerField,通常不需要我们写,一般会自动生成。不指定时,Django会自动生成字段为id的自增长字段。

BooleanField:

布尔字段,为True或者False

NullBooleanField:

允许为Null,True,False

CharField(max_length=最大长度):

字符串类型,max_length表示支持的最大字符串,是必须给的参数。

TextField:

大文本字段,一般超过4000个字,才会使用它。

IntegerField:

整数字段

DecimalField():

浮点数,参数max_digits表示允许的最多位数,

decimal_places表示小数的位数

FloatField;

浮点数,参数和上面的一样,但是没有上面的精确。

DateField:

日期(年月日),参数autu_now=True,表示每次保存的,自动的添加现在的时间

参数auto_now_add=True,表示添加时候的时间,

这两个属性是互斥的,只能存在一个。

TimeField:

时间(时分秒):参数和上面的一样。

DateTimeField:

时间(年月日,时分秒),参数同上。

FileField:

上传文件字段。

ImageField:

继承FileField,对上传的照片进行校验,保证是有效的照片。

公用属性

default:默认值

primary_key:若为True,则是主键,一般搭配AutoField使用。

unique:唯一值

db_index:若为True,则会为此字段创建索引。

db_column:指定字段名字,未指定会使用属性名称。

null:若为True,表示该字段允许为空。

blank:这个属性与后台admin有关,是否允许在后台添加值的时候是否为空。

注意:我们在添加属性的时候如果影响了表结构,就需要迁移,default和blank不影响表结构。

更多模型字段,请参考Django官方文档。写的明明白白。

查询

我们在Django中通过操作模型类去做增删改查,sql语句那么多,我们同样可以进行增删改查。

其中最复杂的也就是查询了。下面我们来看一下。

查询函数

我们在Django中通过:模型类.objects属性调用以下函数来进行查询

get:

返回表中满足条件的一条数据,有且只能有一条,查询出多条会报异常。

查询不到数据也会报异常。

all:

返回全部数据,返回的类型是QuerySet。

filter:

返回符合条件的,和get不同,这个可以返回多条数据。返回的类型是QuerySet。

exclude:

返回不满足此条件的,也是可以返回多条数据,返回类型也是QuerySet。

order_by:

对查询的结果进行排序,返回类型也是QuerySet。

以下我们以模型类为stuinfo是实例。

get实例:

查询id为1的数据:

stuinfo.objects.get(id = 1)

all实例:

查询所有数据:

stuinfo.objects.all()

filter实例:

条件格式:字段名__条件名 = 值

1、等于条件名为exact

查询年龄(age)为18的人

student.objects.filter(age__exact = 18)

2、模糊查询条件名为contains

2.1查询名字(name)中含有张的人

student.objects.filter(name__contains='张')

2.2查询以名字三结尾的人

student.objects.filter(name__endswith='三')

2.3查询以李开头的人

student.objects.filter(name__startswith='李')

3、空查询 isnull

3.1查询备注(context)为空的人

student.objects.filter(context__isnull=True)

3.2查询备注(context)不为空的人

student.objects.filter(context__isnull=False)

4、范围查询 in

查询id等于1和2的人

student.objects.filter(id__in=[1,2])

5、比较查询 gt(大于) lt(小于) gte(大于等于) lte(小于等于)

5.1查询id大于3的人

student.objects.filter(id__gt=3)

5.2查询id大于等于3的人

student.objects.filter(id__gte=3)

5.3查询id小于3的人

student.objects.filter(id__lt=3)

5.4查询id小于等于3的人

student.objects.filter(id__lte=3)

6、日期查询

6.1查询生日(bir_date)是1998年出生的人

student.objects.filter(bir_date__year=1998)

6.2查询生日(bir_date)是5月出生的人

student.objects.filter(bir_date__month=5)

6.3查询生日(bir_date)是1998,1,1以后出生的

from datetime import date

student.objects.filter(bir_date__gt=date(1998,1,1))

exclude实例

查询id不等以1的人

student.objects.exclude(id = 1)

order_by实例

查询所有人按照ids从小到大排序

student.objects.all().order_by('id')

查询所有时,可以省略all()

student.objects.order_by('id')

查询所有人按照ids从大到小排序

student.objects.all().order_by('-id')

也可以根据多个字段排序

根据id和age进行排序

student.objects.all().order_by('id','age')

注意:以上只要返回值为QuerySet类型,都可以再次进行以上任何操作。

Q对象

以上我们都是单个条件进行查询,那如果多个条件呢?

我们可以在上面获取的对象再次进行筛选,也就是注意中说的那句话,但是很麻烦。

因此Django为我们提供了Q模块来帮助我们多条件查询。

首先我们需要导入Q模块:

from django.db.models import Q

Q实例:

在实例之前,在Filter中是可以进行and操作的,但是不能进行or操作。

比如查询id大于3,年龄(age)大于18的人:

student.objects.filter(id__gt=3,age__gt=18)

用Q对象查询 and用Q对象中的&符号:

student.objects.filter(Q(id__gt=3)&Q(age__gt=18))

|对应or

查询id=1或者age大于25的人:

student.objects.filter(Q(id=1)|Q(age__gt=25))

Q对象中还能进行非操作~:

查询id不等于2的人

student.objects.filter(~Q(id=2))

F对象

多条件可以解决,那属性之间的比较怎么解决?

F对象

导入F对象:

from django.db.models import F

查询id大于年龄(age)的人

student.objects.filter(id__gt=F('age'))

聚合函数

在mysql中有sum,count,avg,max,mix等聚合函数,

我们操作模型同样可以达到效果:

导入聚合类模块

from django.db.models import Sum,Avg,Count,Max,Mix

聚合函数实例

使用聚合函数需要使用aggregate来操作

查询所有人的数目

student.objects.all().aggregate(Count('id'))

查询年龄(age)的和

student.objects.all().aggregate(Sum('age'))

其他就不一一实例了。

上面返回的是一个字典:

比如查询的所有人的数目返回:

{'id__count':值}

年龄和:

{'age__sum':值}

key值是字典加双下划线加聚合函数的名字。

count函数

查询所有人的数目也可以这样写

student.objects.all().count()

注意:当返回值类型为QuerySet类型时,我们称他为一个查询集,可以再次进行以上任何操作。

查询集的特性

1、惰性查询

只有当我们使用数据的时候,才会在mysql中去查询。

2、缓存

当我们使用同一个查询集的时候,只有第一次是执行到数据库,然后把结果储存起来,当我们再次使用这个查询集的时候,就会调用我们缓存中的数据。

查询集相当于一个列表,我们取值可以遍历取出,也可以进行下表或者切片取出。

当我们对一个查询集进行切片或下标查询,会返回一个新的查询集。

不同的是我们的切片不允许为负值。

判断一个查询集是否有数据。

查询集.exists(),有返回True,没有返回False

模型类关系

1、一对多关系

例如一个班级对应多个人

我们需要用ForeignKey()来关联我们的模型。

2、多对多

一个老师对应多个学生,一个学生对应多个老师

那么老师表和学生表就是多对多的关系。

我们需要使用ManyToManyField(),那么你会说我定义在那个表里了?定义那个表都行。

3、一对一关系

学生的学号和学生的详细信息表就是一对一的关系。

可以用OneToOneField来定义,定义那个一个类都可以。

关联查询(一对多)

关联实例班级表(classinfo),学生表(stuinfo)

查询班级id为1的所有学生:

# 查询到id为1的班级

c = classinfo.objects.get(id=1)

# 利用关联的表加__set来查询

c.stuinfo__set.all()

反过来,查询id为1的学生的班级名称

# 查询id=1的学生

s = student.objects.get(id=1)

# 直接通过关联的字段来查询

s.关联字段,比如s.c_id

以上很麻烦,我们直接通过模型类来查询

实例:

查询班级表中学生的名字包含张的班级

classinfo.objects.filter(stuinfo__name__contains = '张')

你想要得到那张表,就用那张表去查询。

查询学生表中,班级表中id为1的学生.

# 学生表中有关联的字段,我们通过关联的字段来查询。

stuinfo.objects.filter(c_id__id = 1)

自关联

自关联是一种特殊的一对多的关系,

我们在关键模型类的时候,需要使用ForgignKey('self'),表示关联自己。

同样的查询方式。

管理器

什么是管理器?

我们每次查询的时候都会是模型.objects.xxx。

这个objects是Django帮我们自动生成的管理器对象。通过objects来帮助我们查询信息。

objects是models.Manger的一个对象,也就是说objects继承于models.Manger。

同样我们可以不使用Django帮我们生成的,我们可以自己创建一个。

为什么要自己创建?

1、过滤查询集,比如你查询全部数据,我只让你返回前十条。

2、添加新的方法,比如添加,修改可以封装在里面方面我们使用。

过滤查询集实例

如果我们在models.py中创建一个模型:

# 创建stuinfo表

class stuinfo(model.Model):

# name 字符串类型 最大长度为20

name = mdoels.CharField(max_length=20)

# age 数字类型

age = model.IntegerField()

# 自定义一个管理器对象

# objects是我定义的一个名字,你可以定义成其他的

# stuinfoManage是我定义的管理器的类名,同样你可以定义成其他

objects = stuinfoManage()

# 定义管理类,继承model.Manager

class stuinfoManage(model.Manager):

# 该更返回的查询集

# 重新定义all方法

def all(self):

# 调用父类方法中的all()查询到全部内容

s = super().all()

# 过滤数据,只显示id小于10的数据

s = s.filter(id__lt=10)

# 返回数据

return s

添加新的方法实例

同样我们在上面的stuinfoManage中添加一个新方法添加

class stuinfoManage(model.Manager):

# 该更返回的查询集

# 重新定义all方法

def all(self):

# 调用父类方法中的all()查询到全部内容

s = super().all()

# 过滤数据,只显示id小于10的数据

s = s.filter(id__lt=10)

# 返回数据

return s

# 添加一个添加方法

def stu_create(self,name,age):

# 实例化stuinfo类

# 这里我们给大家介绍一个新的方法

# stuinfo.objects.model 返回的就是stuinfo

# 所以我们这个实例对象不需要s = stuinfo()了

s = self.model

s = s()

s.name = name

s.age = age

s.save()

return s

你能想到为我们的添加方法封装,那Djang的创造者自然也想得到。

我们添加的时候需要:

不过这里需要指定参数传递

student.objects.cretae(name='张三',age=18)

元选项

以上我们都是先创建好模型再去迁移,创建表,

试想,如果我们的数据库已经存在呢?

比如我们在数据库创建的表是stu,

我们的模型是stuinfo,我们可以给他指定一个数据库里的表

class stuinfo(model.Model):

name = mdoels.CharField(max_length=20)

age = model.IntegerField()

# 我们需要在模型里再定义一个Meta类

class Meta:

db_table = 'stu'

即可。

orm映射的表名也即是我们在自动生成表的表名是:

应用名_类名。

所以你去修改数据的表名也是可以实现的。

另:前端知识希望自己补充.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档