增删改查操作
一、模型类中的属性说明
1.1 model类示例:
class People(models.Model):
name = models.CharField(verbose_name='项目名称', help_text='项目名称', max_length=20,
unique=True)
leader = models.IntegerField(verbose_name='项目负责人', help_text='项目负责人')
1.2 修改数据库表信息
如果不指定默认的表名为‘子应用名_model类名’。
在上面的model类中添加Meta子类,该子类中就可以修改数据表的一些信息。修改完成后需要重新生成并执行迁移脚本才会生效。
class People(models.Model):
class Meta:
db_table = 'tb_projects' # 修改表名,如果不指定默认的表名为‘子应用名_model类名’
verbose_name = '项目表' # 指定创建的数据表中文描述信息
verbose_name_plural = '项目表' # 指定创建的数据表中文描述信息(复数)
#abstract = True # 迁移时不需要生成这张表
1.3 models的更多字段
-
models.AutoField
:自增列= int(11),必须指明
primary_key=True
。 -
models.CharField
:指定为字符串字段,必须指明
max_length
参数。 -
models.BooleanField
:布尔类型。 -
models.DateTimeField
:日期类型。 -
models.ForeignKey
:一对多的外键,第一个参数为父表名(子应用名.父表model类名),第二个参数为on_delete(级联关系)。 -
models.OneToOneField
:一对一的外键,第一个参数为父表名(子应用名.父表model类名),第二个参数为on_delete(级联关系)。 -
models.ManyToManyField
:多对多的外键,第一个参数为父表名(子应用名.父表model类名)。
1.4 models的更多参数
models.py文件中添加数据字段有一些参数,我们在此说明一下这些常用参数的意义。
-
primary_key=True
:定义该字段为主键,默认为False,如果定义了一个字段为True,那么就不会自动生成id字段。 -
max_length
:指定字段的最大长度,CharField必须得设置max_length参数。 -
verbose_name
和
help_text
:指定中文的描述,在admin后台站点以及在接口文档平台中会使用到。 -
unique=True
:设置唯一约束,数据库中该字段不允许重复,默认为False。 -
default
:指定当前字段的默认值。 -
null=True
:指定当前字段允许保持null空值,默认为False。 -
blank=True
:指定前端在创建数据时允许不输入,默认为False。 -
choices=set
:指定choices为一个set嵌套set的对象,代表数据库存一个缩写,和前端交互的时候使用全拼,类似一个缩写字典查询。set的例子:GENDER_CHOICE =((u’M’, u’Male’),(u’F’, u’Female’),) -
auto_now_add=True
:DateTimeField的参数,把创建这条数据的时间作为该字段的时间,,只修改一次。默认为False。 -
auto_now=True
:DateTimeField的参数,更新这条数据时,把更新时间作为该字段的时间,只要修改就更新。默认为False。 -
on_delete
:级联关系。-
on_delete=models.CASCADE
:当父表数据删除之后,对应的从表数据会被自动删除。 -
on_delete=models.SET_NULL
:当父表数据删除之后,对应的从表数据的外键字段会被自动设置为null。 -
on_delete=models.PROTECT
:当父表数据删除时,如果存在对应的从表数据,那么会抛出异常。 -
on_delete=models.SET_DEFAULT, default=''
:父表数据删除之后,对应的从表数据的外键字段会被自动设置为default参数指定的值
-
-
related_name='interfaces'
:用于设置父表模型对象获取从表数据时,使用的属性名称
二、查看生成的sql语句
from django.db import connection
connection.queries
三、新增数据
3.1 方式一
直接调用model的类,传入参数,需要注意的是要导入model的类,并且传参完成后需要调用save方法才能够操作成功
from django.views import View
from projects.models import Projects
class project(View):
def get(self, request):
one_project = Projects(name='XXX项目', leader='Aaron', desc='这是一个描述')
one_project.save()
one_interface = Interfaces(name='登录接口', tester='Aaron', projects_id=one_project.id) # 添加子表数据时,外键可以使用主表数据.id的方式添加
#one_interface = Interfaces(name='登录接口', tester='Aaron', projects=one_project) # 添加子表数据时,外键也可以使用主表数据的方式添加
one_interface.save()
return HttpResponse(' ')
3.2 方式二
使用模型类.objects为manager对象的create方法(关键字参数)提交,此方式不需要save。
class project(View):
def get(self, request):
Projects.objects.create(name='XXX项目2', leader='Aaron', desc='这是一个描述')
return HttpResponse(' ')
四、更新数据
4.1 方式一
先获取需要修改的数据,再用赋值的方式修改,完成后save提交。
class project(View):
def get(self, request):
one_project = Projects.objects.get(id=2) # 获取需要修改的数据
one_project.name = '更新的xxx项目' # 更新
one_project.save() # 提交操作
return HttpResponse(' ')
4.2 方式二
通过filter取出待修改的对象,再使用update方法更新需要更新的字段。这种方法不需要save。(如果前面filter取出的是多条数据,那么这些数据都会更新)
class project(View):
def get(self, request):
one_project = Projects.objects.filter(id=2).update(leader='new_aaron')
return HttpResponse(' ')
五、查询数据
5.1 读取多条数据
使用模型类.objects.all()获取当前表的所有数据,返回的是QuerySet对象,类似于列表,但不是列表,支持列表的方法去操作。
QuerySet对象为了提升性能是惰性查找,只有需要用到数据(len、取值、for)时,才会执行sql语句。
class project(View):
def get(self, request):
qs = Projects.objects.all()
qs=list(qs)
print(qs) # [<Projects: XXX项目>, <Projects: 更新的xxx项目>]
return HttpResponse(qs)
5.2 读取一条数据
5.2.1 方式一
可以使用模型类.objects.get()获取一条数据,需要注意的是,如果查出来是多条数据或数据不存在,会报错。查询条件有多个时,使用逗号隔开。
class project(View):
def get(self, request):
qs = Projects.objects.get(id=1)
return HttpResponse(qs)
5.2.2 方式二
使用模型类.objects.filter方法获取一条数据,返回的是QuerySet对象。
如果查询的结果为空,那么会返回空的QuerySet对象。
如果查询的结果超过一条,也会返回多条结果所在的QuerySet对象。
class project(View):
def get(self, request):
qs = Projects.objects.filter(id=1)
return HttpResponse(qs)
5.2.3 filter查询类型
filter查询支持多种查询类型(where条件)。格式为:
字段名__查询类型=具体值
-
Projects.objects.filter(id__exact=1)
查询id等于1的数据。 -
Projects.objects.filter(id__gt=1)
查询id大于1的数据。 -
Projects.objects.filter(id__gte=1)
查询id大于等于1的数据。 -
Projects.objects.filter(id__lt=2)
查询id小于2的数据。 -
Projects.objects.filter(id__lte=2)
查询id小于等于2的数据。 -
Projects.objects.filter(id__in=[1,3])
查询id等于1和3的数据。 -
Projects.objects.filter(name__contains='金融')
查询name包含’金融’的数据。 -
Projects.objects.filter(name__icontains='x')
查询name包含’x’的数据(忽略x的大小写)。 -
Projects.objects.filter(name__startswith='x')
查询name以’x’开头的数据。 -
Projects.objects.filter(name__istartswith='x')
查询name以’x’开头的数据(忽略x的大小写)。 -
Projects.objects.filter(name__endswith='x')
查询name以’x’结尾的数据。 -
Projects.objects.filter(name__iendswith='x')
查询name以’x’结尾的数据(忽略x的大小写)。 -
Projects.objects.filter(外键字段__从表字段__contains='登录')
查询从表的name包含’登录’的数据。
5.2.3.1 查询集的特性
-
惰性查询(不操作就不会生成sql语句)
- 会生成sql的操作:
- 通过数字索引取值,但不支持负值索引
- 支持切片操作
- 支持.first()方法,可以取出查询集中的第一个元素,为模型类对象
- 支持.last()方法,可以取出查询集中的最后一个元素,为模型类对象
- 支持len(查询集对象),获取查询集的长度,也可以使用.count()方法
- 支持.exists()方法,来判断查询集中是否有元素,如果有元素,那么返回True,否则返回False
- 支持for循环迭代
-
链式调用
-
a.查询集对象可以多次调用filter方法,进行过滤。
Projects.objects.filter(id__gt=1).filter(name__startswith='x')
- b.多个filter中的过滤条件为与的关系。
-
c.在一个filter方法中,可以写多个条件,每个条件之间以“逗号”分割,每个条件为与的关系。
Projects.objects.filter(id__gt=1, Projects.objects.filter(id__gt=1)
-
a.查询集对象可以多次调用filter方法,进行过滤。
5.3 Q查询
需要导入Q
from django.db.models import Q
-
与
Projects.objects.filter(Q(name__contains='x') & Q(leader='Aaron'))
-
或
Projects.objects.filter(Q(name__contains='x') | Q(leader='Aaron'))
5.4 排序操作
- .默认是以id主键升序来排序的
- 查询集对象.order_by(‘字段名1’,‘字段名2’)
- 默认指定的字段名为升序
- 可以在字段名的前面添加-,代表以降序来排序
5.5 聚合运算
# 根据主表Projects的id分组查询从表Interfaces的数量
qs = Projects.objects.values('id').annotate(Count('interfaces'))
qs = Projects.objects.values('id').annotate(interfaces=Count('interfaces'))
- values和annotate为固定用法
- 聚合运算需要设置为从表名小写
- 使用外键id作为关联条件,同时会把外键id作为分组条件
- 默认查询id和聚合运算的值
- 聚合运算的别名会自动设置为:从表名小写__聚合函数名小写
-
可以给聚合运算设置关键词参数,会作为聚合运算的别名
格式:
主表.objects.values('主键').annotate(聚合运算别名=Count('外键'))
六、删除数据
one_project = Projects.objects.get(id=1) # 获取需要删除的数据
one_project.delete() # 调用delete方法删除