Django鼓励开发人员进行相对独立的模块开发,这种开发模式在工作中被称为:解耦合,就是指在开发中将项目看成几个独立的模块进行开发,降低模块之间的耦合性。在这种思路下,django数据开发采用了mvc和mvt设计模式,和ORM机制
更改数据库为mysql
在settings中
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',##引擎
'NAME': 'stu', ## 库名
'USER': 'root', ## 用户名
'PASSWORD': '123123',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
pip install pymysql
create database stu charset=utf8;
CharField 字符串类型
IntegerField 整形
DecimalField 浮点型 其中5代表五位数,2代表两位小数
DateField 日期
EmailField 邮箱
TextField 文本类型
BooleanField 布尔类型
django ORM会帮助我们自动创建一个主键
1. 在数据迁移之前,确定配置是否完成
python manage.py check
2.排错
第一个错误
原因:django 模式使用python2 版本的mysql数据库模块,python3 使用的是pymsql模块
第二个错误
原因:django默认检测pymysql的版本,修改源码,去掉检测
解决办法:
3.数据迁移
python manage.py makemigrations
原因: python3当中 字符串没有 decode
app01-person表是根据我们写的类模型创建的表,默认名字是 子应用名字-模型名字
数据迁移
python manage.py makemigrations app的名字 生成一个迁移文件
python manage.py migrate app的名字 名字可写可不写 使用迁移文件,进行表同步
创建Django管理的用户 python manage.py createsuperuser
修改站点管理后台为中文:
注意:在模型中修改的内容对数据库产生影响后需要重新生成迁移文件和同步表结构,如果是修改模型的内容是关于站点管理后台的内容不涉及数据库则不需要迁移文件和同步表结构。
字段类型
CharField varchar类型,需要指定长度
IntegerField 整形
DecimalField 浮点型 需要指定最大长度和小数点位数
DateField 日期 datetime
ForeignKey 做外键
# to 设置关联表
# to_field 关联表要关联的键名,默认为关联表中的id,可以不写
# on_delete 当删除关联表中的数据的时候,从表做什么行为,
# CASCADE 当关联表中数据删除的时候,外键所在表中的数据也会被删除
# SET_NULL 当关联表中数据删除的时候,外键所在表中的外键设置为空
# SET_DEFAULT 当关联表中数据删除的时候,外键所在表中的外键设置一个默认值
# PROTECT 关联保护,当关联表的数据被删除的时候,报异常,
# DO_NOTHING 当关联表中数据删除的时候,外键所在的表不做任何事情
字段属性
max_length 最大长度
verbose_name 备注,站点管理中用于显示字段为中文
max_digits 浮点型最大长度
decimal_places 小数点位数
auto_now = True 获取的是当前时间
null = True 可为空,默认是不为空
元数据
class Meta:
db_table 修改表的名字
verbose_name 备注,站点管理中用于显示模型名字为中文,会出现s
verbose_name_plural 显示复数名称
ordering= ['-age'] 指定排序
增加
查询
1.all()
# all 方法
date = Person.objects.all()
# print (date)
# print (date[0].name)
# print (date[0].age)
# print (date[0].height)
for one in date:
print (one.height)
print (one.name)
2 .get方法
# get 方法
data = Person.objects.get(id=1)
print (data.name)
print (data.age)
3 .filter 方法(类似于sql中的 where)
# filter 方法
data = Person.objects.filter(name="zhangsan")
print (data)
4 .first方法 和last 方法
first 返回一个对象,返回符合条件的第一条数据(对象)
last 返回一个对象,返回符合条件的最后一条数据(对象)
data = Person.objects.filter(name="zhangsan").first()
print (data.age)
data = Person.objects.filter(name="zhangsan").last()
print(data.age)
5 . order_by 排序
# 升序
# data = Person.objects.all().order_by("age")
# 降序
data = Person.objects.all().order_by("-age")
for one in data:
print (one.age)
data = Person.objects.all().order_by("age","-name")
6 .exclude()
data = Person.objects.exclude(name="zhangsan")
for one in data:
print (one.name)
7 .values ,count ,exists,切片
values queryset [duixiang,duixiang,duixiang]
返回的是一个queryset 内容不是实力对象,而是具体数据的字典
data = Person.objects.filter(name="zhangsan").values()
print (data)
count 返回的是符合当前条件的数据的条数
data = Person.objects.filter(name="zhangsan").count()
print (data)
exists 返回一个 True或者Flase 判断是否存在
data = Person.objects.filter(name="libai").exists()
print (data)
切片
data = Person.objects.order_by("id")[2:5]
print (data)
8 .双下换线查询
__lt 小于
data = Person.objects.filter(id__lt=3)
print (data)
__gt 大于
data = Person.objects.filter(id__gt=3)
print (data)
__gte 大于等于
data = Person.objects.filter(id__gte=3)
print (data)
__in 包含 select * from stu where id in (1,2,3,4);
data = Person.objects.filter(id__in = [1,2,3])
print (data)
exclude 不包含
order_info=OrderInfo.objects.filter(order_id=1).exclude(status__in=[0,4]).first()
__range 范围
data = Person.objects.filter(id__range = [1,5])
print (data)
__startswith 像 like j% endswith 像 %j
data = Person.objects.filter(name__startswith="j")
print (data)
__endswith
__contains 包含 大小写敏感
data = Person.objects.filter(name__contains="w")
print (data)
__icontains 包含,大小写不敏感
data = Person.objects.filter(name__icontains="w")
print(data)
注意:
Queryset:查询集,不是python列表,也叫结果集,表示从数据库中获取的一个对象集合
使用如下的方法的时候返回:
特性:
使用如下方法返回对象
修改
save 注意:拿到的结果是对象还是查询集合
# 先查询到数据,然后进行重新赋值,然后执行save 进行保存
data = Person.objects.get(id=2)
data.name = "python"
data.save()
data = Person.objects.filter(name="wangwu").all()
for one in data:
if one.id == 4:
one.age=21
else:
one.age = 23
one.save()
update
Person.objects.filter(id=2).update(name="java")
删除
delete方法
Person.objects.filter(id=7).delete()
# 增加出版社
# Publish.objects.create(name='清华出版社',address = '北京')
# Publish.objects.create(name='中国出版社',address = '北京朝阳')
# Publish.objects.create(name='河南出版社',address = '洛阳')
# 增加书
# Book.objects.create(name='python入门',publish_id = 1)
# publish = Publish.objects.get(name='中国出版社')
# Book.objects.create(name='python入门', publish_id=publish.id)
# 第二种方法
# Book.objects.create(name='python核心编程',publish = Publish.objects.get(name='中国出版社'))
# 第三种方法
# 正向操作 从外键所在的表到主表叫正向
book = Book()
book.name= '笨办法学python'
book.publish = Publish.objects.get(name='河南出版社')
book.save()
# 反向操作 从主表到从表 叫反向
publish_obj = Publish.objects.get(name="中国出版社")
publish_obj.book_set.create(name='pythonWeb开发')
查询
# 查询的第一种方法
# publish = Publish.objects.get(name="中国出版社")
# book = Book.objects.filter(publish_id=publish.id).all()
# for x in book:
# print (x.name)
# 查询第二种方法
# 正向查询 从外键所在的表到主表叫正向
# 查询 pythonWeb开发 属于哪一个出版社
# book = Book.objects.filter(name='pythonWeb开发').first()
# print (book.name)
# print (book.publish.name)
# 查询第三种方法
# 反向查询 从主表到从表 叫 反向查询 _set
publish = Publish.objects.get(name='中国出版社')
book = publish.book_set.all()
print (book)
修改
1.save
book = Book.objects.get(id=1)
book.publish = Publish.objects.get(name='中国出版社')
book.save()
2.update
Book.objects.filter(name='java').update(publish = Publish.objects.get(name='清华出版社'))
publish_obj = Publish.objects.get(name='清华出版社')
Book.objects.filter(name='python核心编程').update(publish=publish_obj)
3.set反向
public = Publish.objects.get(name='河南出版社')
book = Book.objects.get(id=4)
book1 = Book.objects.get(id=3)
public.book_set.set([book,book1])
删除
先删除外键所在的表,在删除关联表
Book.objects.get(id=2).delete()
Publish.objects.get(name='清华出版社').delete()
class Person(models.Model):
# id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
height = models.DecimalField(max_digits=5,decimal_places=2,verbose_name="身高",null=True)
birthday = models.DateField(verbose_name="生日",auto_now=True)
def __str__(self):
return str(self.name)
class Meta:
db_table = 'person'
verbose_name = "用户"
verbose_name_plural = verbose_name
# ordering= ['-age','id','name']
class Teacher(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField(default=0)
gender = models.CharField(max_length=8)
person = models.ManyToManyField(to=Person)
class Meta:
db_table = 'teacher'
# 新学员 秦秦 想学 laozhang 课 create 正向操作
# teacher_obj = Teacher.objects.filter(name='laozhang').first()
# teacher_obj.person.create(name="秦秦",age=16,height=192)
# 老学员张三 想学 laowang 的课 创建关系的操作 正向操作
# teacher_obj = Teacher.objects.filter(name='laowang').first()
# person_obj = Person.objects.filter(name="zhangsan").first()
# teacher_obj.person.add(person_obj)
## 反向操作
teacher_obj = Teacher.objects.filter(name="laoliu").first()
person_obj = Person.objects.filter(name="秦秦").first()
person_obj.teacher_set.add(teacher_obj)
查询
def manytomanyget(request):
## 正向 反向
## 正向查询
# 查到老师信息,寻找这个老师教的所有学生
# teacher_obj = Teacher.objects.filter(name='laoliu').first()
# person = teacher_obj.person.all()
# print (person)
## 查到学生的信息,寻找该学生的老师
## 反向查询
person_obj = Person.objects.filter(name='秦秦').first()
teacher_obj = person_obj.teacher_set.all().values()
print (teacher_obj)
return HttpResponse("多对多查询")
更改
def manytomanyupdate(request):
# 修改老刘交的学生 10 3 改成 老刘只交id为 1 2 3 4 5 学生
# 正向 从外键所在表 -》 关联表 teacher -》 person
# 第一种
# teacher_obj = Teacher.objects.filter(name="laoliu").first()
# teacher_obj.person.set([1,2,3,4,5])
# 第二种
# teacher_obj = Teacher.objects.filter(name="laoliu").first()
# person1 = Person.objects.filter(name="java").first()
# person2 = Person.objects.filter(name="秦秦").first()
# ## set 后面要放一个 列表,列表中可以是id 还可以是 对象
# teacher_obj.person.set([person1,person2])
## 反向修改
# 第一种
# person_obj = Person.objects.filter(name='java').first()
# person_obj.teacher_set.set([2])
# 第二种 放对象
person_obj = Person.objects.filter(name='java').first()
teacher1 = Teacher.objects.filter(name="laoliu").first()
teacher2 = Teacher.objects.filter(name="laowang").first()
person_obj.teacher_set.set([teacher1,teacher2])
删除
# remove() 解除对象之间的关系
# 正向操作
# 秦秦同学 不学老张的课了
# person_obj = Person.objects.filter(name='秦秦').first()
# teacher_obj = Teacher.objects.filter(name="laozhang").first()
# teacher_obj.person.remove(person_obj)
# 反向操作
# teacher_obj = Teacher.objects.filter(name="laoliu").first() ## 查询教师数据
# person_obj = Person.objects.filter(name='zhangsan').first() ## 查询学生数据
# person_obj.teacher_set.remove(teacher_obj)
# delete() 删除对象数据,以及对象之间的关系
# laoliu 离职
# Teacher.objects.filter(name="laoliu").first().delete()
# java 同学 退学了
Person.objects.filter(name="java").first().delete()
通过aggregate调用聚合函数
aggregate () 是一个queyset的方法,意思是:返回一个包含数据的键值对的字典
键名:聚合值的表示符号,值:聚合函数计算的结果。
def jttest(request):
data = Person.objects.all().aggregate(Avg("age"))
print(data)
data = Person.objects.all().aggregate(avg_age = Avg("age"),sum_age = Sum("age"))
print (data)
return HttpResponse("集合查询")
F对象: 用于比较同一个模型中的两个字段的值
Q对象: 用于处理多条件中的逻辑关系 and or not
def Qtest(request):
### and
data = Book.objects.filter(num=10,salled=100).all()
print (data)
# and 关系
data = Book.objects.filter(Q(num__gt=10)&Q(salled=100)).all()
print(data)
## or
data =Book.objects.filter(Q(num__gt=10)|Q(salled=100)).all()
print (data)
## not
data = Book.objects.filter(~Q(num=10)|~Q(salled=100)).all()
print (data)
return HttpResponse("Q obj test")