一. ORM框架---object relation mapping
二.安装mysql 和navicat 查看视频
三.修改配置项目
第一步:创建项目
django-admin startproject chapter01
cd chapter01
python manage.py startapp books
第二步:settings.py修改
//第一处
installed apps:{
'books'
}
//第二处
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'demo',
'HOST':'localhost',
'PORT': 3306,
'USER':'root',
'PASSWORD':'myy040715'
}
}
第三步:安装mysql(数据库设置)
mysql -uroot -p
create database test;
show databases;
第四步:安装驱动程序
pip install .\mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl
第五步:运行此文件
python manage.py runserver
运行项目如果报上面的错误:
原因:较高版本的mysql的ssl默认是开启的
解决方案:关闭ssl
第一步:先查看ssl开启情况
登录mysql之后,输入该命令:
mysql> SHOW VARIABLES LIKE '%ssl%';
第二步:修改配置文件my.ini
# 路径:C:\ProgramData\MySQL\MySQL Server 8.0
[mysqld]
skip_ssl # 忽略ssl
第三步:重启mysql服务
ctrl+shift+esc按键调出任务管理器—>服务—>找到mysql服务—>右键重新运行
第四步:重新执行命令:
mysql> SHOW VARIABLES LIKE '%ssl%';
第五步:运行此文件
python manage.py runserver
第六步:models.py 文件里面进行设置
class BookInfo(models.Model):
name = models.CharField(max_length=20, verbose_name="名称")
pub_date = models.DateField(verbose_name="发布日期")
readcount = models.IntegerField(default=0, verbose_name="阅读量")
commentcount = models.IntegerField(default=0, verbose_name="评论量")
is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")
def __str__(self):
return self.name
第七步:检查settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'books',
]
第八步:生成迁移文件
python manage.py makemigrations
第九步:执行迁移文件
python manage.py migrate
四.创建一个新的类名(ImageInfo)
第一步:添加类
在应用中的models.py文件配置BookInfo和ImageInfo类,同时把他们相同的部分提取到抽象类里面(BaseMobel)中
from django.db import models
# Create your models here.
class BaseModel(models.Model):
name = models.CharField(max_length=20,verbose_name="名称")
pub_date = models.DateField(verbose_name="发布日期")
class Meta:
abstract = True #只能当作基类不能当作实例
#继承了上面的属性
class BookInfo (BaseModel):
readcount = models.IntegerField(default=0,verbose_name="阅读量")
commentcount = models.IntegerField(default=0,verbose_name="评论量")
is_delete = models.BooleanField(default=False,verbose_name="逻辑删除")
class ImageInfo(BaseModel):
likecount = models.IntegerField(default=False, verbose_name="点赞量")
def __str__(self):
return self.name
第二步:生成迁移文件,执行迁移文件
python manage.py makemigrations
python manage.py migrate
第二步:查看
在数据库(demo)中 查看会出现两个数据表(books_bookinfo),(books_imageinfo)
五.数据库的增删改查
第一步:添加数据库
在控制台上输入数据库的进入端口
python manage.py shell
在控制台中导入部署函数
from books.models import BookInfo
在控制台中添加数据(数据的顺序要和数据库里面的顺序一致)
1.create添加数据
BookInfo.objects.create(name='孙悟空',pub_date='1937-1-2',readcount=100,commentcount=70,is_delete=0
在控制台可以查看其数据(用定义一个值的方法)
a=BookInfo.objects.create(name='孙悟空',pub_date='1937-1-2',readcount=100,commentcount=70,is_delete=0)
a.name
a.commentcount
2.save()方法添加数据
在控制台中导入部署函数
from books.models import BookInfo
添加数据
bookinfo=BookInfo(name='Python web',pub_date='1937-01-09',readcount=100,commentcount=70,is_delete=0)
bookinfo.save()
第二步:查询数据库
1.all()方法
all()方法查询模型在数据库映射的表中的所有记录,返回值是一个QuerySet对象,该对象是一个类似列表的结构,它支持for循环、索引(不支持负索引)、切片等操作。
索引:
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
all_info=BookInfo.objects.all()
all_info //索引的方法查看所有的数据,返回值是一个QuerySet对象
all_info[0]
all_info[0].name
for循环:
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
info_list=[info for info in all_info]
info_list
info_list=[info.name for info in all_info]
info_list//查看的是所有的name
2.filter()方法
filter()方法根据查询条件查询数据表,返回满足条件的数据,返回值是一个QuerySet对象。
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
book_info=BookInfo.objects.filter(id=3)
book_info //查看id为3的数据,返回是QuerySet对象
book_info[0]
book_info[0].name//查看的是一个值(name)
3.exclude()方法
exclude()方法根据查询条件查询数据库,返回不满足条件的数据,返回值是一个QuerySet对象。
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
ex
ex_info=BookInfo.objects.exclude(id__gte=3)
ex_info
ex_info[0]
ex_info[0].name
4.get()方法
get()方法根据查询条件进行查找,返回符合条件的一条记录,返回值是一个模型对象。
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
//get()方法 返回符合条件的一条记录,一个模型
book_obj=BookInfo.objects.get(id=3)
book_obj //返回的一条记录
book_obj.name
5.获取排列数据order_by()方法
name=BookInfo.objects.order_by('name')
for i in name:
... print(i.name)
6.value接受可选参数*fields
all_info=BookInfo.objects.all()
all_info//返回值是一个QuerySet对象。
all_info=BookInfo.objects.values()
all_info//是一个value queryset返回字典
all_info=BookInfo.objects.values_list()
all_info #字典
7.contains查看数据库
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
res=BookInfo.objects.filter(name__contains='三')
res
res[0].name
第三步:删除数据
//delete()方法 对象的方法
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
book_obj=BookInfo.objects.get(id=3)
book_obj
book_obj.delete()
第四步:修改数据库
python manage.py shell
//在控制台中导入部署函数
from books.models import BookInfo
res=BookInfo.objects.filter(id=1).update(is_delete=1)
res
六. 多表查询定义的类
创建一个应用hello
在应用中的models.py定义类
//自定义管理器
from django.db import models
# Create your models here.
class CountryManager(models.Manager):
def country_name_prefix(self):
#查询所有结果
all_countries = self.all()
for country in all_countries:
country.country_name = '国家' + country.country_name
return all_countries
class Country(models.Model):
country_code = models.CharField(max_length=20)
country_name = models.CharField(max_length=50)
objects = CountryManager()
class Meta:
db_table = 'country'
def __str__(self):
return self.country_name
生成迁移文件,执行迁移文件
python manage.py makemigrations
python manage.py migrate
在数据库里面添加数据
//在控制台上部署函数
from hello.models import Country
country=Country(country_name='china',country_code='01')
country.save()
country=Country(country_name='us',country_code='02')
country.save()
1.一对多管理器
在应用hello.models.py里面添加类
class PersonManager(models.Manager):
def get_queryset(self):
return super(PersonManager,self).get_queryset().filter(person_nation__exact=1)
class Person(models.Model):
person_name = models.CharField(max_length=20)
person_age = models.IntegerField(default=0)
person_money = models.IntegerField(default=0)
person_nation = models.ForeignKey(Country,on_delete=models.CASCADE,db_column='f')
objects = PersonManager()
class Meta:
db_table = "person"
生成迁移文件,执行迁移文件
python manage.py makemigrations
python manage.py migrate
2.一对多正向查询
一对多关系中正向查询的语法格式为:
当前模型对象.关联字段.关联模型中要查询的字段
from hello.models import Person
p=Person.objects.get(id=1)
p.person_name
// 当前模型对象.关联字段.关联模型中要查询的字段
country_name=p.person_nation.country_name
country_name
3.一对多反向查询
一对多关系中反向查询的语法格式为:
当前模型对象.关联模型表名(小写)_set.all()
from hello.models import Country
c=Country.objects.get(id=1)
c
p_country=c.person_set.all()
p_country
//当前模型对象.关联模型表名(小写)_set.all()
p=c.person_set.all()
p//返回值是一个QuerySet
p[0].person_name
p[1].person_name//返回是一个值
4. 一对一正向查询
先在hello.models里面添加President类
class President(models.Model):
president_name=models.CharField(max_length=20)
president_gender=models.CharField(max_length=20)
president_nation_id = models.OneToOneField(Country,on_delete=models.CASCADE,db_column='f')
class Meta:
db_table = "president"
然后生成迁移文件,执行迁移文件
python manage.py makemigrations
python manage.py migrate
然后在终端中进入环境
python manage.py shell
一对一关系中正向查询的方式与一对多关系中正向查询的方式相同,其语法格式如下:
当前模型对象.关联字段.关联模型中要查询的字段
from hello.models import President
p=President.objects.get(id=1)
p
//当前模型对象.关联字段.关联模型中要查询的字段
p.president_nation_id.country_name
5.一对一反向查询
一对多一系(关系?)中反向查询的语法格式为:
当前模型对象.关联模型表名(小写).关联模型中要查询的字段
from hello.models import Country
c=Country.objects.get(id=1)
c
//当前模型对象.关联模型表名(小写).关联模型中要查询的字段
c.president.president_name
七. F和Q对象
1.F对象
使用F对象的语法格式如下:
F(字段名)
//首先要引用数据库和F,Q对象
from books.models import BookInfo
from django.db.models import F,Q
BookInfo.objects.filter(readcount__gt=F('commentcount'))
a=BookInfo.objects.filter(readcount__gt=F('commentcount'))
a[0].name
a[1].name
2.Q对象
使用Q对象的语法格式如下:
Q(属性名___运算符=值)
#首先要引用数据库和F,Q对象
from books.models import BookInfo
from django.db.models import F,Q
BookInfo.objects.filter(Q(readcount__gt=50),Q(id__lt=3))
BookInfo.objects.filter(Q(readcount__gt=50)|Q(id__lt=3))
BookInfo.objects.filter(~Q(id__lt=3))
3. 聚合函数
#首先导入BookInfo数据库和Avg(平均对象),min(最小值对象)
from books.models import BookInfo
from django.db.models import Avg,Min
BookInfo.objects.aggregate(Avg('readcount'),Min('commentcount'))
BookInfo.objects.aggregate(avg=Avg('readcount'),min=Min('commentcount'))
八. 执行原始SQL语句
1.使用Manager.raw()方法执行SQL查询语句
Manager.raw()方法接收一个原始SQL查询语句,返回一个RawQuerySet对象,该对象是一个查询集,与QuerySet对象一样支持迭代操作。raw()方法的语法格式如下:
Manager.raw(raw_query, params=None,translations=None)
- raw_query:表示原始的SQL语句。
- params:查询条件参数,接收列表或字典类型的数据。
- translations:表示字段映射表,接收存储查询字段与模型字段映射关系的字典类型数据。
//在控制台上导入数据库
from hello.models import Person
p=Person.objects.raw('select * from Person')
p//返回值为一个RawQuerySet
res=[i for i in p]//for循环
res
res[0]
res[1:]
#raw()方法将查询语句中的字段映射至模型字段,因此raw()方法中字段的顺序并不影响查询出的结果。
p=Person.objects.raw('select id.person_name from Person')
p
p=Person.objects.raw('select person_name from Person')
p
需要注意的是,Django中使用主键来区分模型实例,因此raw()方法的原始SQL查询语句中必须包含主键,否则会抛出invalidQuery 异常。
raw()方法根据字段名称查询数据,raw()方法中的SQL语句可以使用as关键字为字段设置别名。
#在控制台上导入数据库
from hello.models import Person
res=Person.objects.raw('select id,person_name as p_name from person')
res
res[0]
res[0].person_name
res[0].p_name
通过raw()方法的translations参数也可以实现此查询。
#在控制台上导入数据库
from hello.models import Person
query_map={"pk":"id","p_age":"person_age","p_name":"person_name"}
p=Person.objects.raw("select * from person",translations=query_map)
res=[i for i in p]
res
res[0]
res[0].person_name
res[0].pk
在查询数据时,可以使用raw()方法中参数params为原始SQL语句传递查询参数,该参数可以为一个列表或字典类型的数据。
#在查询数据时,可以使用raw()方法中参数params为原始SQL语句传递查询参数,该参数可以为一个列表或字典类型的数据。
param=['person_name']
p_name=Person.objects.raw('slect %s from person',param)
p_name
#使用“%(key)s”作为占位符可以为raw()方法的参数params传递一个字典类型的参数。
param={"id":1}
p_name=Person.objects.raw('select * from person where id=%(id)s',param)
p_name #返回是一个RawQuerySet对象
2.raw()方法也可以执行数据库的增删改
2.1.添加数据(insert):
#在控制台上部署函数
from studentinfo.models import Student
student=Student.objects.raw("insert into student(id, sid, name, sex, sclass, grade, academy, major, email, pwd)Values(3, '0003', '小明', '男', '3班', '三年级', '软件与大数据', '区块链技术应用', '[email protected]', '12345')")
student.query._execute_query()
2.2修改数据库
student=Student.objects.raw("update student set name=%s where id=1",['葛老师'])
student.query._execute_query()
2.3.删除数据
student=Student.objects.raw("delete from student where id=1")
student.query._execute_query()
3. 利用游标对象执行SQL语句
django.db.connection提供默认数据库连接,使用connection.cursor()方法可以获取数据库游标对象,使用游标对象的execute()方法可以执行原始的SQL语句。
fetchone()与fetchall()也是数据库游标对象的常用方法,它们分别返回查询集中的一条/全部记录。
#在控制台上导入部署函数
from django.db import connection
cursor=connection.cursor()
cursor
cursor.execute('select * from person')#5
#查询全部记录
cursor.fetchall()
#查询一条记录
cursor.fetchone()