一、django 查询的方法
def detail(request,id):
#查询一个对象
xxx = xxx.objects.filter(id=id).first()
#如果使用上边的方法查询,如果数据不存在会爆异常,如果想让 程序不报错,需加一个捕获异常,如下:
try:
xxx = xxx.objects.get(id=id)
except xxx.DoesNotExist as e:
print(e)
return render(request,'app05/jianli.html',locals())
查询集
当查询结果是多个的时候,django-ORM会返回一个 查询集(QuerySet) ,表示从数据库中获取对象的 集合 。
查询集可以使用过滤器进行再次处理。
例如:查询阅读量大于20且评论数大于30的书
book = Book.objects.filter(b_read__gt=20)
book.filter(b_comment__gt=30)
<QuerySet [<Book:天龙八部>]>
查询集的两大特性
惰性查询:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。
缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。
限制查询集
可对查询集进行取下标或切片操作,类似sql语句中的limit条件查询,不支持负数索引
如:xxx.objects.all()[1:3]
查询阅读数大于20的结果,再取下标为1 的数据
book = Book.objects.filter(b_read__gt=20)
book[1]
<Book: 雪山飞狐>
二、django关联
模型类关系
1.关系字段类型:多对多(ManyToManyField),一对多(ForeignKey),一对一(OneToOneField),自关联
2.一对多关系
3.多对多关系
关联查询
1.通过对象进行关联查询
2.通过模型类进行查询
3.自关联:是一种特殊的一对多关系
表关系的建立
建立学院信息表、学生信息表、课程表、学生详情表,
表关系如下:
1.学院信息表 《= 一对多 ForeignKeyField =》 学生信息表
2.学生信息表 《= 一对一 OneToOneField =》 学生详细信息表
3.课程表 《= 多对多 ManyToManyField =》学生信息表
在model中建立以下几个模型类:
models.py
from django.db import models
学院表
class Department(models.Model):
d_id = models.AutoField(primary_key=True)
d_name = models.CharField(max_length=30)
def __str__(self):
return "Department<d_id=%s,d_name=%s>"%(self.d_id,
self.d_name)
学生表
class Student(models.Model):
s_id = models.AutoField(primary_key=True)
s_name = models.CharField(max_length=30)
department = models.ForeignKey('Department',
null=True, #可以为空值
related_name='student', # 反向查询用(就不_set了:d1.student_set.all() -》d1.student )
on_delete=models.CASCADE) # 外键,自动关联表的主键 级联删除
def __str__(self):
return "Student<s_id=%s, s_name=%s,department_id=%s >"%(self.s_id,
self.s_name,
self.department_id)
学生选课表
class Course(models.Model):
c_id = models.AutoField(primary_key=True)
c_name= models.CharField(max_length=30)
student = models.ManyToManyField('Student',
related_name='course',
) # 多对多 生成第三张关系表
def __str__(self):
return "Course<c_id=%s,c_name=%s,student=%s>"%(self.c_id,self.c_name,self.student)
学生详情表
class Stu_detail(models.Model):
s_id = models.OneToOneField('Student',on_delete=models.CASCADE) # 一对一, 级联删除
s_age = models.IntegerField()
gender = models.BooleanField(default=1)
city = models.CharField(max_length=30)
def __str__(self):
return"s_id=%s,s_age=%s,s_gender=%s"(self.s_id,self.s_age,self.gender)
一对多表关系数据的添加:
往数据表student中添加数据的第一种方式:
s1 = Student(s_name='xiaoming',department_id=1)
s1.save()
1
2
往数据表student中添加数据的第二种方式:
先在Department里面创建一条数据d1再进行操作
1.s2 = Student(s_name='小红')
2.s2.department_id=d1
3.s2.save()
表关联对象的访问:
s1.department
属性取值,会拿到的=d1
通过管理器反向访问
d1.student_set.all()
在Foreignkey里面设置related_name='student',这样就可以直接用名字而不是_set的形式了
d1.student.all()
这个是实例对象
s1.departmnet
下面3个是管理器
d1.student
s1.course
c1.student
处理关联对象的一些方法:
# 一对多,多的那头就有这个管理器,就有以下方法
# 管理器才能用add,create,clear,remove方法
d1 = Department.objects.get(d_id=1)
s1 = Student.objects.get(s_id=1)
c1 = Course.objects.get(c_id=1)
# print(d1,s1,c1)
print(d1.student.all()) # 查询到学院的所有学生, 通过一对多关系,管理器.all()
print(s1.department) # 模型类里面的属性,直接访问
print(c1.student) # 管理器 多对多
print(c1.student.all()) # 报名这个课程的学生
# print(s1.course_set.all()) # 学生报了哪些课, 反向查询,可以用related_name去改
print(s1.course.all()) # 学生报了哪些课, 反向查询用related_name 管理器
create(**kwargs) 添加不存在的数据 ,将数据直接存入数据库
创建一个新的对象,将它保存并放在关联的对象集返回新创建的对象
s1.course.create(c_name='C语言程序设计') # 会同时向两个表格添加数据
d1.student.create(s_name='小帅') # 给d1学院添加一个学生(之前不存在数据库中)
多表查询—-跨关联关系的查询:
查询学院名字为‘计算机学院’的学生的信息
Student.objects.filter(department__d_name='计算机学院')
查询学生名字中包含 '小' 的学生的学院信息
Department.objects.filter(student__s_name__contains='小')
查询学号为1的学生所有的课程
Course.objects.filter(student__s_id=1)
查询报了课程1的所有的学生
Student.objects.filter(course__c_id=1)
查询报了'python'课程的的学生的所属学院的信息
Department.objects.filter(student__course__c_name='python')
django模型类拓展
1.模型实例方法
str()对象转换为字符串时调用
save()保存模型对象到数据库,orm框架会转换为对应的insert或update语句
delete()删除模型对象,orm框架会转换为对应的delete语句
模型类的属性
objects:管理器,是models.Manager类型的对象,用于和数据库进行交互
管理器Manager
自定义管理器类主要用于:
1.修改原始查询集,重写all()方法
2.向管理器类添加新方法,如向数据库插入数据
- 修改原始查询集,重写all()方法
如:
打开booktest/models.py文件,定义类BookInfoManager
图书管理器class BookInfoManager(models.Manager): def all(self): #默认查询未删除的图书信息
调用父类的成员语法为:super().方法名 return super().all().filter(isDelete=False)
在模型类BookInfo中定义管理器
class BookInfo(models.Model):
books = BookInfoManager()
- 在管理器类中定义创建对象的方法
如:
打开booktest/models.py文件,定义方法create。
class BookInfoManager(models.Manager):
... #创建模型类,接收参数为属性赋值 def create_book(self, title, pub_date): #创建模型类对象self.model可以获得模型类
book = self.model()
book.btitle = title
book.bpub_date = pub_date
book.bread=0
book.bcommet=0
book.isDelete = False # 将数据插入进数据表
book.save() return book
为模型类BookInfo定义管理器books语法如下
class BookInfo(models.Model):
books = BookInfoManager()
调用语法如下:
调用:book=BookInfo.books.create_book("abc",date(1980,1,1))
元选项
如:
from django.db import models
class Ox(models.Model):
horn_length = models.IntegerField()
class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"
常用元选项
db_table
该模型所用的数据表的名称:
db_table = 'music_album'
ordering
对象默认的顺序,获取一个对象的列表时会按照这个字段排序:
它是一个字符串的列表或元组。每个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。
例如:按照pub_date字段的倒序排序,这样写:
ordering = ['-pub_date']
要按照pub_date字段的正序排序,这样写:
ordering = ['pub_date']
注意:排序并不是没有任何代价的操作。你向ordering属性添加的每个字段都会产生你数据库的开销。你添加的每个外键也会隐式包含它的默认顺序。
verbose_name
对象的一个易于理解的名称,为单数:
如果此项没有设置,Django会把类名拆分开来作为自述名,比如CamelCase 会变成camel case,
verbose_name = "pizza"
verbose_name_plural
该对象复数形式的名称:
如果此项没有设置,Django 会使用verbose_name + 's'。
一般都是和verbose_name一起使用
verbose_name = "pizza"
verbose_name_plural = verbose_name
网友评论