模型、属性、表、字段之间的关系:一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段

属性

定义属性时,需要的字段类型,都被定义在django.db.models.fields目录下,为方便使用,导入到django.db.models

逻辑删除

对于重要的数据作逻辑删除,不做物理删除,实现方法是定义isdDelete属性,类型为BooleanField,默认值为False

字段类型

AutoField:

一个根据实际ID自动增长的IntegerField,通常不指定,如果不指定,一个主键字段将自动添加到模型中

CharField(max_length=字符长度):

字符串,默认的表单样式是TextInput

TextField:

大文本字段,一般超过4000使用,默认的表单控件是Textarea

IntegerField:

整数字段

DecimalField(max_digits=None,decimal_places=None):

使用python的Decimal实例表示的十进制浮点数,max_digits表示位数总数,decimal_places表示小数点后的数字位数

FloatField:

使用python的float实例来表示浮点数

BooleanField:

True/Flase,默认表单控制是CheckboxInput

NullBooleanField:

支持null、True、Flase三种值

DateField(auto_now=False,auto_now_add=False):

使用python中的datetime.date实例表示的日期,auto_now表示每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是当前日期。auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建时的时间戳,它总是使用当前日期。

TimeField、DateTimeField、FileField、ImageField

sage = models.IntegerField(db_column='age') #db_column修改字段名称,如果不设置则默认是属性名称
#null:如果为True,Django将空值以NULL存储到数据库中,默认值为False
#blanke:如果为True,则该字段允许为空白,默认值为False null是数据库范畴的概念,blank是表单验证范畴的
#db_column:字段的名称
#db_index:若值为True,则表中会为此字段创建索引
#default:默认值
#primary_key:若为True,则该字段会成为模型的主键字段
#unique:如果为True,该字段在表中必须有唯一值

元选项

在模型类中定义Meta类,用于设置元信息

class Students(models.Model):
...
...
class Meta:
db_table="students" #定义数据表名,推荐使用小写字母,数据表名默认为项目名小写_类名小写
ordering=['id'] #对象的默认排序字段,获取对象列表时使用 ['-id']代表降序

插入数据

#cmd mysql
insert into grades(gname,gdate,ggirlnum,gboyuym,isDelete) values("python01","2017-2-4",10,50,0),values("python01","2017-2-4",10,50,0);
#查看某条数据
select *from students limit2;

自定义模型管理器

如果定义模型类没有指定,则默认是objects

stuObj=models.Mangaer();
#有了上面的定义,则原Students.objects.get(pk=1)->Students.stuObj.get(pk=1),此时objects就不存在了

自定义管理器Manager类

模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器

作用:向管理器类中添加额外的方法;修改管理器返回的原始查询集(重写get_queryset()方法)

class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False)
#super(StudentsManager,self).get_queryset()得到原来的全集

创建对象

#方法1
#models.py
@classmethod
def createStudent(cls,name,age,gender,contend,grade,
lastT,createT,isD=False):
stu=cls(sname=name,sage=age,sgender=gender,
scontend=contend,sgrade=grade,lastTime=lastT,
createTime=createT,isDelete=isD)
return stu

#views.py
def addstudent(request):
grade=Grades.objects.get(pk=1)
stu=Students.createStudent("刘德华",34,True,"Hello",grade,"2017-8-10","2017-8-11")
stu.save()
return HttpResponse("添加成功")
#方法2
#models.py
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager, self).get_queryset().
filter(isDelete=False)

def createStudent(self,name,age,gender,contend,grade,
lastT,createT,isD=False):
stu=self.model()
stu.sname=name
stu.sage=age
stu.sgender=gender
stu.scontend=contend
stu.lastTime=lastT
stu.createTime=createT
return stu

#views.py
def addstudent2(request):
grade=Grades.objects.get(pk=1)
stu=Students.stuObj2.createStudent("刘德华",34,True,"Hello",
grade,"2017-8-10","2017-8-11")
stu.save()
return HttpResponse("添加成功")

模型查询

查询集表示从数据库中获取的对象集合,查询集可以有多个过滤器,过滤器就是一个函数,基于所给的参数限制查询集结果,从sql角度来说,查询集合select语句等价,过滤器就像where条件

在管理器上调用过滤器方法返回查询集,查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用;

惰性执行:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据

返回查询集的方法(过滤器):all(),filter(key=value).filter(key=value)…,exclude()过滤掉符合条件的数据,order_by()排序,values()一条数据就是一个对象(字典),多条数据就是一个列表

返回单个数据:get(),count(),first(),last(),exists()

get()没找到或者有多个对象都会引发异常

count()返回查询集中的对象个数

first()/last()返回查询集第一/最后一个对象

exists()判断查询集中是否有数据,如果有数据返回True

限制查询集:

#返回前5条
studentList=Students.stuObj2.all()[0:5] #注意:这里的下标不能是负数
#urls.py
url(r'^stu/(\d+)/$',views.stupage)
#views.py
#分页显示
def stupage(request,page):
page=int(page)
studentList=Students.stuObj2.all()[(page-1)*5:page*5]
return render(request,'myapp/students.html',
{'students':studentList})

查询集的缓存:

概述:每个查询集都包含一个缓存,来最小化的对数据库访问

字段查询:

概述:实现了sql中的where,作为方法filter()、exclude()、get()的参数

语法:属性名称_比较运算符=值

外键:属性名_id

转义:类似sql中的like语句,like语句中使用%是为了匹配占位 如果要匹配数据中的%(where like ‘\%’)

比较运算符:

exact:判断,大小写敏感

contains:是否包含,大小写敏感

#views.py
#名字中包含孙的
def studentsearch(request):
studentsList=Students.stuObj.filter(sname__contains="孙")
return render(request,"myapp/students.html",{"student":studentsList})

startwith、endwith:以value开头或结尾,大小写敏感

以上4个在前面加上i就表示大小写不敏感,iexact、icontains…

isnull、isnotnull:是否为空/非空

in:是否包含在范围内

pk__in=[2,4,6,8,10]

gt、gte、lt、lte:大于、大于等于、小于、小于等于

year、month、day、week_day、hour、minute、second

跨关联查询:(视频中暂时出错)

处理join查询:模型类名__属性名__比较运算符

gradeList=Grades.stuObj2.all().filter(students__contend__contains='刘德华') #Grades-班级里的  students__contend__contains-学生contend中包含
#学生描述中包含有“刘德华”这三个字的数据是属于哪个班级的

查询快捷:pk 代表的主键

聚合函数

需要先导入相应的函数

from django.db.models import Max

使用aggregate()函数返回聚合函数的值

Avg、Count、Max、Min、Sum

maxAge=Students.stuObj2.aggregate(Max('age')) #拿到的是最大值而不是数据

F对象、Q对象

F对象:可以使用模型的A属性与B属性进行比较

from django.db.models import F,Q
def grades(request):
Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)

Q对象:

概述:过滤器方法中的关键字参数,条件为and模式

需求:进行or查询

解决:使用Q对象

from django.db.models import F,Q
def grades(request):
Grades.objects.filter(Q(pk__lte=3) | Q(sage_gt=50))) #pk小于等于3或者年龄大于50的
#Grades.objects.filter(~Q(pk__lte=3)) pk大于3的

Shiroha