Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库。
- 模型、属性、表、字段间的关系
####<p style="color:DeepSkyBlue">定义模型</p>
django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列。
<p style="color:red">由于django的查询方式,不允许使用连续的下划线。</p> 定义属性时,需要字段类型,字段类型被定义在\`\`\`django.db.models.fields\`\`\`目录下,为了方便使用,被导入到\`\`\`django.db.models\`\`\`中,定义模型时先导入\`\`\`from django.db import models\`\`\`,通过models.Field创建字段类型的对象,赋值给属性。 <p style="color:red">注意:对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False</p>####<p style="color:DeepSkyBlue">字段类型</p>
-
AutoField:一个根据实际ID自动增长的<span style="color:Coral">IntegerField</span>,通常不指定如果不指定,一个主键字段将自动添加到模型中。 -
CharField(max_length=字符长度):字符串,默认的表单样式是<span style="color:Coral">TextInput</span>。 -
TextField:大文本字段,一般超过4000使用,默认的表单控件是<span style="color:Coral">Textarea</span>。 -
IntegerField:整数 -
DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数,DecimalField.max_digits(位数总数),DecimalField.decimal_places(小数点后的数字位数)。 -
FloatField:用Python的float实例来表示的浮点数。 -
BooleanField:true/false 字段,此字段的默认表单控制是<span style="color:Coral">CheckboxInput</span>。 -
NullBooleanField:支持null、true、false三种值。 -
DateField([auto_now=False, auto_now_add=False]):使用Python的<span style="color:Coral">datetime.date</span>实例表示的日期,DateField.auto_now,每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false,DateField.auto_now_add,当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。
<p style="color:red">注意:auto\_now\_add, auto\_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果</p>
-
TimeField:使用Python的<span style="color:Coral">datetime.time</span>实例表示的时间,参数同DateField。 -
DateTimeField:使用Python的<span style="color:Coral">datetime.datetime</span>实例表示的日期和时间,参数同DateField。 -
FileField:一个上传文件的字段。 -
ImageField:继承了<span style="color:Coral">FileField</span>的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image。
####<p style="color:DeepSkyBlue">字段参数</p>
说明:通过字段选项,可以实现对字段的约束,在字段对象时通过关键字参数指定。
-
null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False。 -
blanke:如果为True,则该字段允许为空白,默认值是 False。
<p style="color:red">注意:null是数据库范畴的概念,blank是表单验证证范畴的。</p>
-
db_column:字段的名称,如果未指定,则使用属性的名称。 -
db_index:若值为 True, 则在表中会为此字段创建索引。 -
default:默认值。 -
primary_key:若为 True, 则该字段会成为模型的主键字段。 -
unique:如果为 True, 这个字段在表中必须有唯一值。 -
upload_to='article':图片、文件字段的参数,表示文件上传到某个文件夹。
####<p style="color:DeepSkyBlue">模型间关系</p>
-
<p style="color:red">一对一关系 : OneToOneField</p>
class Student(models.Model): name = models.CharField() info = OneToOneField(B)
class StudentInfo(models.Model): tel = models.CharField() addr = models.CharField()
stu = Student() meta = StudentInfo() stu.info # 正向查询-通过学生查询信息 meta.student # 反向查询,通过信息查询学生
-
<p style="color:red">一对多关系 : ManyToManyField</p>
class Student(models.Model): name = models.CharField() grade = ForeignKey(Grade)
class Grade(models.Model): gname = models.CharField()
stu = Student() grade = Grade() stu.grade # 正向查询,通过学生查询班级名 grade.student_set # 反向查询,通过班级名查询学生
-
<p style="color:red">多对多关系 : ManyToManyField</p>
class Student(models.Model): name = models.CharField() course = ManyToManyField(Course)
class Curse(models.Model): cname = models.CharField()
stu = Student() course = Course() stu.course_set # 正向 查询学生选修的课程 course.student_set # 反向 查询选修课程的学生名
####<p style="color:DeepSkyBlue">模型元选项</p>
在模型类中定义Meta类,用于设置元信息
1class A(models.Model): 2 pass 3 class Meta: 4 db_table = 'a' # 定义数据表名,推荐使用小写字母,数据表名默认为项目名小写_类名小写 5 ordering = ['id'] # 对象的默认排序字段,获取对象的列表时使用,'id'-升序,‘-id’降序 6
####<p style="color:DeepSkyBlue">模型成员</p>
-
类属性
-
objects:是Manager类型的一个对象,作用是与数据库进行交互,当定义模型类是没有指定管理器,则Django为模型创建一个名为objects的管理器。
自定义管理器
<p style="color:red">当为模型指定模型管理器,Django就不在为模型类生成objects模型管理器。</p>1class Students(models.Model): 2 # 自定义模型管理器 3 # 当自定义模型管理器,objects就不存在了 4 stuObj = models.Manager() 5
- 自定义管理器Manager类
模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器,作用是向管理器类中添加额外的方法,修改管理器返回的原始查询集(重写get_queryset()方法)。
1class StudentsManager(models.Manager): 2 def get_queryset(self): 3 return super(StudentsManager,self).get_queryset().filter(isDelete=False) # 重写get_queryset()方法对查询集进行过滤 4 5class Students(models.Model): 6 stuObj2 = StudentsManager() 7
- 创建对象的方法
(1).在模型类中增加一个类方法
1class Students(models.Model): 2 #定义一个类方法创建对象 3 @classmethod 4 def createStudnet(cls, name, age, gender, contend, grade, lastT, createT, isD=False): 5 stu = cls(sname = name, sage = age, sgender = gender, scontend = contend, sgrade = grade, lastTime = lastT, createTime = createT, isDelete=isD) 6 return stu 7# 调用 8Students.createStudent() 9
(2). 在定义管理器中添加一个方法
1class StudentsManager(models.Manager): 2 def get_queryset(self): 3 return super(StudentsManager,self).get_queryset().filter(isDelete=False) 4 def createStudnet(self, name, age, gender, contend, grade, lastT, createT, isD=False): 5 stu = self.model() 6 # print(type(grade)) 7 stu.sname = name 8 stu.sage = age 9 stu.sgender = gender 10 stu.scontend = contend 11 stu.sgrade = grade 12 stu.lastTime = lastT 13 stu.createTime = createT 14 return stu 15
####<p style="color:DeepSkyBlue">模型查询</p>
查询集表示从数据库获取的对象集合,查询集可以有多个过滤器,过滤器就是一个函数,基于所给的参数限制查询集结果,创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据。
<p style="color:Lime ">创建学生模型</p><p style="color:Lime ">创建班级模型</p>1class Student(models.Model): 2 s_name = models.CharField(max_length=10,unique=True) # 指定学生名唯一 3 s_age = models.IntegerField() # 学生姓名 4 s_gender = models.BooleanField(default=True) # 学生性别默认为True 5 isDelete = models.BooleanField(default=false) # 设置逻辑删除字段 6 grade = models.ForeignKey(Grade) # 关联班级 7 class Meta: 8 db_table = 'student' # 指定表名 9 ordering = ['id'] # 以id排序 10 def __str(self)__: 11 return self.s_name # 查询集的返回显示学生姓名 12 13class StudentManager(models.Manager): 14 def get_queryset(self): 15 return super(StudentsManager,self).get_queryset().filter(isDelete=False) # 自定义模型管理器,重写父类get_queryset()方法,过滤查询集 16
<p style="color:Lime ">创建课程模型</p>1class Grade(models.Model): 2 g_name = models.CharField(max_length=10,unique=True) # 创建班级名指定唯一 3 4 class Meta: 5 db_table = 'grade' 6 ordering = ['id'] 7 def __str(self)__: 8 return self.g_name
<p style="color:Lime ">创建学生信息模型</p>1class Course(models.Model): 2 c_name = models.CharField(max_length=10) # 课程名 3 start_date = models.DateField(auto_now_add) # 开课日期 4 end_date = models.DateField(auto_now_add) # 结束日期 5 stu = models.ManyToManyField(Student) 6 class Meta: 7 db_table = 'course' 8 ordering = ['start_date'] 9 def __str(self)__: 10 return self.c_name 11 12
1class StudentInfo(models.Model): 2 phone = models.IntegerField() # 手机号 3 address = models.CharField(max_length=20) # 地址 4 stu = OneToOneField(Student) 5 class Meta: 6 db_table = 'studentinfo' 7 8
<p style="color:DeepSkyBlue">过滤器</p>
1Student.objects.all() # 返回查询集中的所有数据 2 3Student.objects.filter(pk=3) # 返回符合条件的数据 4 5Student.objects.filter(s_age=20).filter(s_gender=True) # 满足两种条件的查询方式一 6 7Studen.objects.filter(s_age=20,s_gender=False) # 满足两种条件的查询方式二 8 9Studen.objects.exclude(s_name='tom') # 过滤掉符合条件的数据,查询不满足条件的其他数据 10 11Studen.objects.order_by('s_age') # 以年龄排序,升序 12 13Studen.objects.order_by('-s_age') # 以年龄排序,降序 14 15Studen.objects.values() # 将所有对象及属性返回 16 17Studen.objects.values('s_name') # 返回所有对象的名字 18 19
-
<p style="color:red">返回单个数据</p>
Studen.objects.get(pk=1) # 返回一个满足条件的对象,如果没有找到符合条件的对象,会引发"模型类.DoesNotExist"异常,如果找到多个对象,会引发"模型类.MultipleObjectsReturned"异常
Studen.objects.filter(s_gender=True).count() # 返回当前查询集中的对象个数
Studen.objects.filter(s_gender=True).first() # 返回查询集中的第一个对象
Studen.objects.filter(s_gender=True) # 返回查询集中的最后一个对象
Studen.objects.filter(s_name='tom').exists() # 判断查询集中是否有数据,如果有数据返回True
-
<p style="color:red">限制查询集</p>
studentsList = Student.objects.all()[0:5] # 注意:下标不能是负数
查询集的缓存:在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存。
####<p style="color:DeepSkyBlue">字段查询</p>
<p style="color:red">比较运算符</p>
1Studen.objects.filter(s_name__contains='王') # 查询名字包含王的学生,大小写敏感 2 3Studen.objects.filter(s_name__startswith='孙') # 查询名字以开头的学生,大小写敏感 4 5Studen.objects.filter(s_name__endswith='雨') # 查询名字以结尾的学生,大小写敏感 6
<p style="color:red">以上四个在前面加上i,就表示不区分大小写iexact、icontains、istartswith、iendswith</p>
<p style="color:red">跨关联查询</p>1StudenInfo.objects.filter(address isnull) # 查询地址是空的学生信息 2 3StudenInfo.objects.filter(address isnotnull) # 查询地址不是空的学生信息 4 5Studen.objects.filter(pk in (2,4,6)) # 查询pk在(2,4,6)的学生 6 7Studen.objects.filter(s_age__gt=20) # 查询年龄大于20的学生 8 9Studen.objects.filter(s_age__gte=20) # 查询年龄大于等于20的学生 10 11Studen.objects.filter(s_age__lt=30) # 查询年龄小于30的学生 12 13Studen.objects.filter(s_age__lte=30) # 查询年龄小于等于30的学生 14 15Course.objects.filter(start_date__year=2016) # 查询开课课程在2016年的课程 16 17Course.objects.filter(start_date__year=2016,start_date__month=10) # 查询开课课程在2016年10月的课程 18 19# year-month-day-week_day-hour-minute-second 20 21
1Studen.objects.filter(course__c_name__contains='程序设计') # 查询课程中带有程序设计的课程被选择的学生 2
<p style="color:red">聚合函数</p>
使用<p style="color:red">aggregate()</p>函数返回聚合函数的值。使用哪个聚合函数就导入。
<p style="color:red">F对象</p>1from django.db.models import Max,Min,Sum,Avg,Count 2 3maxAge = Student.objects.aggregate(Max('s_age')) 4 5minAge = Studen.objects.aggregate(Min('s_age')) 6 7sumAge = Studen.objects.aggregate(Sum('s_age')) 8 9avgAge = Studen.objects.aggregate(Avg('s_age')) 10 11countAge = Studen.objects.aggregate(Count('s_age')) 12
可以使用模型的A属性与B属性进行比较。
<p style="color:red">Q对象</p>1from django.db.models import F 2 3Studen.objects.filter(pk__gte=F('s_age')) # 查询学生中主键大于年龄的学生 4 5Studen.objects.filter(pk__gt=F('s_age')+20) # 查询学生中主键大于年龄加20的学生 6 7
过滤器的方法中的关键字参数,条件为And模式
1from django.db.models import Q对象 2 3Studen.objects.filter(Q(pk__lt=5) | Q(s_age__gt=20)) # 查询主键小于5或年龄大于20的学生 4 5Studen.objects.filter(~Q(pk__lt=5)) # 取反,查主键大于5的学生。