ORM
映射关系:
ORM:object relationship mapping
表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象
创建表(建立模型)
数据库的迁移
python manage.py makemigrations #数据库迁移
python manage.py migrate
x
1
python manage.py makemigrations #数据库迁移
2
python manage.py migrate
创建数据库表字段
一、字段
1、models.AutoField 自增列= int(11)
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField 字符串字段
必须 max_length 参数
3、models.BooleanField 布尔类型=tinyint(1)
不能为空,Blank=True
4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
5、models.DateField 日期类型 date
对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField 日期类型 datetime
同DateField的参数
7、models.Decimal 十进制小数类型= decimal
必须指定整数位max_digits和小数位decimal_places
8、models.EmailField 字符串类型(正则表达式邮箱)=varchar
对字符串进行正则表达式
9、models.FloatField 浮点类型= double
10、models.IntegerField 整形
11、models.BigIntegerField 长整形
integer_field_ranges ={
'SmallIntegerField':(-32768,32767),
'IntegerField':(-2147483648,2147483647),
'BigIntegerField':(-9223372036854775808,9223372036854775807),
'PositiveSmallIntegerField':(0,32767),
'PositiveIntegerField':(0,2147483647),
}
12、models.IPAddressField 字符串类型(ip4正则表达式)
13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
参数protocol可以是:both、ipv4、ipv6
验证时,会根据设置报错
14、models.NullBooleanField 允许为空的布尔类型
15、models.PositiveIntegerFiel 正Integer
16、models.PositiveSmallIntegerField 正smallInteger
17、models.SlugField 减号、下划线、字母、数字
18、models.SmallIntegerField 数字
数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField 字符串=longtext
20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField 字符串,地址正则表达式
22、models.BinaryField 二进制
23、models.ImageField图片 upload_to='avatar/',保存图片的路径 default="/avatar/default.png"
24、models.FilePathField文件
class Meta:
verbose_name_plural = "权限表" #修改admin中显示表名字
二、字段参数
1、null=True
数据库中字段是否可以为空
2、blank=True
django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
auto_now 自动创建---无论添加或修改,都是当前操作的时间
auto_now_add 自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default 默认值
8、verbose_name Admin中字段的显示名称
9、name|db_column 数据库中的字段名称
10、unique=True 不允许重复
11、db_index = True 数据库索引
12、editable=True 在Admin里是否可编辑
13、error_messages=None 错误提示
14、auto_created=False 自动创建
15、help_text 在Admin中提示帮助信息
16、validators=[]
17、upload-to #保存文件的路径
tags = models.ManyToManyField(
to="Tag",
through='Article2Tag', #自定义创建多对多的表
through_fields=('article', 'tag'), #定义自定义表的字段
)
x
1
一、字段
2
1、models.AutoField 自增列= int(11)
3
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
4
2、models.CharField 字符串字段
5
必须 max_length 参数
6
3、models.BooleanField 布尔类型=tinyint(1)
7
不能为空,Blank=True
8
4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
9
继承CharField,所以必须 max_lenght 参数
10
5、models.DateField 日期类型 date
11
对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
12
6、models.DateTimeField 日期类型 datetime
13
同DateField的参数
14
7、models.Decimal 十进制小数类型= decimal
15
必须指定整数位max_digits和小数位decimal_places
16
8、models.EmailField 字符串类型(正则表达式邮箱)=varchar
17
对字符串进行正则表达式
18
9、models.FloatField 浮点类型= double
19
10、models.IntegerField 整形
20
11、models.BigIntegerField 长整形
21
integer_field_ranges ={
22
'SmallIntegerField':(-32768,32767),
23
'IntegerField':(-2147483648,2147483647),
24
'BigIntegerField':(-9223372036854775808,9223372036854775807),
25
'PositiveSmallIntegerField':(0,32767),
26
'PositiveIntegerField':(0,2147483647),
27
}
28
12、models.IPAddressField 字符串类型(ip4正则表达式)
29
13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
30
参数protocol可以是:both、ipv4、ipv6
31
验证时,会根据设置报错
32
14、models.NullBooleanField 允许为空的布尔类型
33
15、models.PositiveIntegerFiel 正Integer
34
16、models.PositiveSmallIntegerField 正smallInteger
35
17、models.SlugField 减号、下划线、字母、数字
36
18、models.SmallIntegerField 数字
37
数据库中的字段有:tinyint、smallint、int、bigint
38
19、models.TextField 字符串=longtext
39
20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
40
21、models.URLField 字符串,地址正则表达式
41
22、models.BinaryField 二进制
42
23、models.ImageField图片 upload_to='avatar/',保存图片的路径 default="/avatar/default.png"
43
24、models.FilePathField文件
44
45
class Meta:
46
verbose_name_plural = "权限表" #修改admin中显示表名字
47
48
二、字段参数
49
1、null=True
50
数据库中字段是否可以为空
51
2、blank=True
52
django的 Admin 中添加数据时是否可允许空值
53
3、primary_key = False
54
主键,对AutoField设置主键后,就会代替原来的自增 id 列
55
4、auto_now 和 auto_now_add
56
auto_now 自动创建---无论添加或修改,都是当前操作的时间
57
auto_now_add 自动创建---永远是创建时的时间
58
5、choices
59
GENDER_CHOICE = (
60
(u'M', u'Male'),
61
(u'F', u'Female'),
62
)
63
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
64
6、max_length
65
7、default 默认值
66
8、verbose_name Admin中字段的显示名称
67
9、name|db_column 数据库中的字段名称
68
10、unique=True 不允许重复
69
11、db_index = True 数据库索引
70
12、editable=True 在Admin里是否可编辑
71
13、error_messages=None 错误提示
72
14、auto_created=False 自动创建
73
15、help_text 在Admin中提示帮助信息
74
16、validators=[]
75
17、upload-to #保存文件的路径
76
77
78
tags = models.ManyToManyField(
79
to="Tag",
80
through='Article2Tag', #自定义创建多对多的表
81
through_fields=('article', 'tag'), #定义自定义表的字段
82
)
83
建立一个图书管理系统
图书管理系统
1、创建表
python manage.py makemigrations #数据库迁移
#在/app01下面的models.py
from django.db import models
# Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
author = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5, decimal_places=2)
python manage.py makemigrations #数据库迁移
#=======================================================华丽的分割线
#上面表创建之后会在app01/migrations下面自动添加了一个py文件 里面对应了创建的表,根据上面的类来区分,这只是第一步
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-25 11:45
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('nid', models.AutoField(primary_key=True, serialize=False)),
('title', models.CharField(max_length=32)),
('author', models.CharField(max_length=32)),
('publishDate', models.DateField()),
('price', models.DecimalField(decimal_places=2, max_digits=5)),
],
),
]
42
1
#在/app01下面的models.py
2
from django.db import models
3
4
# Create your models here.
5
6
class Book(models.Model):
7
nid = models.AutoField(primary_key=True)
8
title = models.CharField(max_length=32)
9
author = models.CharField(max_length=32)
10
publishDate = models.DateField()
11
price = models.DecimalField(max_digits=5, decimal_places=2)
12
13
python manage.py makemigrations #数据库迁移
14
#=======================================================华丽的分割线
15
#上面表创建之后会在app01/migrations下面自动添加了一个py文件 里面对应了创建的表,根据上面的类来区分,这只是第一步
16
# -*- coding: utf-8 -*-
17
# Generated by Django 1.11.6 on 2017-10-25 11:45
18
from __future__ import unicode_literals
19
20
from django.db import migrations, models
21
22
23
class Migration(migrations.Migration):
24
25
initial = True
26
27
dependencies = [
28
]
29
30
operations = [
31
migrations.CreateModel(
32
name='Book',
33
fields=[
34
('nid', models.AutoField(primary_key=True, serialize=False)),
35
('title', models.CharField(max_length=32)),
36
('author', models.CharField(max_length=32)),
37
('publishDate', models.DateField()),
38
('price', models.DecimalField(decimal_places=2, max_digits=5)),
39
],
40
),
41
]
42
输出结果:

第二步
python manage.py migrate

会生成一个

第三步
在ORM/settings.py里面找到DATABASES这里是链接数据库的地方
添加
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog', #你的数据库名称
'USER': 'root', #你的数据库用户名
'PASSWORD': '', #你的数据库密码
'HOST': '', #你的数据库主机,留空默认为localhost
'PORT': '3306', #你的数据库端口
}
11
1
DATABASES = {
2
'default': {
3
'ENGINE': 'django.db.backends.mysql',
4
'NAME': 'blog', #你的数据库名称
5
'USER': 'root', #你的数据库用户名
6
'PASSWORD': '', #你的数据库密码
7
'HOST': '', #你的数据库主机,留空默认为localhost
8
'PORT': '3306', #你的数据库端口
9
10
}
11
在进行python manage.py makemigrations
**注意:这里会报错

总结:报错 error loading MySQLdb module: No module named 'MySQLdb'.
2版本支持mysqldb模块,3支持pymysql,为什么报这个错误,因为我现在没有告诉它我用的哪一个模块去走,默认是用mysqldb去走的,然后我用的3版本所以要告诉它我用pymysql就可以了
那么怎么弄呢
在app01应用下面添加pymysql就好了
import pymysql
pymysql.install_as_MySQLdb()
2
1
import pymysql
2
pymysql.install_as_MySQLdb()

这样在进行一次python manage.py migrate

可以看到,已经插入进数据库了
那么现在要在前端页面上展示了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
<script src="/static/jquery-3.2.1.js"></script>
<script src="/static/bootstrap-3.3.7/js/bootstrap.js"></script>
</head>
<body>
<div class="container-fluid">
<!-- Button trigger modal -->
<a href="/add/"><button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">添加</button></a>
<table class="table table-hover table-bordered">
<tr>
<td>编号</td>
<td>书名</td>
<td>作者</td>
<td>日期</td>
<td>价格</td>
<td>操作</td>
</tr>
#通过for循环来
{% for foo in book_list %}
<tr>
<th>{{ foo.nid }}</th>
<th>{{ foo.title }}</th>
<th>{{ foo.author }}</th>
<th>{{ foo.publishDate|date:"Y-m-d" }}</th>
<th>{{ foo.price }}</th>
<th>
<a href="{{ foo.nid }}">
<button class="btn btn-success">修改</button>
</a>
<a href="/del/{{ foo.nid }}">
<button class="btn btn-danger">删除</button>
</a>
</th>
</tr>
{% endfor %}
</table>
</div>
</body>
</html>
#==================================================我是华丽的分割线
from django.shortcuts import render,redirect
from app01 import models
# Create your views here.
def index(request):
#从数据库取出来的数据
book_list=models.Book.objects.all()
return render(request,"index.html",{"book_list":book_list})
#删除
def deltitle(request,id):
models.Book.objects.filter(nid=id).delete()
return redirect("/index/")
#添加
def add(request):
if request.method=="POST":
name=request.POST.get("name")
bookname = request.POST.get("bookname")
author=request.POST.get("author")
time=request.POST.get("time")
price=request.POST.get("price")
models.Book.objects.create(nid=name,title=bookname,author=author,publishDate=time,price=price)
return redirect("/index/")
return render(request,"add.html")
78
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
<meta charset="UTF-8">
5
<title>Title</title>
6
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
7
<script src="/static/jquery-3.2.1.js"></script>
8
<script src="/static/bootstrap-3.3.7/js/bootstrap.js"></script>
9
</head>
10
<body>
11
<div class="container-fluid">
12
<!-- Button trigger modal -->
13
<a href="/add/"><button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">添加</button></a>
14
<table class="table table-hover table-bordered">
15
<tr>
16
<td>编号</td>
17
<td>书名</td>
18
<td>作者</td>
19
<td>日期</td>
20
<td>价格</td>
21
<td>操作</td>
22
</tr>
23
#通过for循环来
24
{% for foo in book_list %}
25
<tr>
26
27
<th>{{ foo.nid }}</th>
28
<th>{{ foo.title }}</th>
29
<th>{{ foo.author }}</th>
30
<th>{{ foo.publishDate|date:"Y-m-d" }}</th>
31
<th>{{ foo.price }}</th>
32
<th>
33
<a href="{{ foo.nid }}">
34
<button class="btn btn-success">修改</button>
35
</a>
36
<a href="/del/{{ foo.nid }}">
37
<button class="btn btn-danger">删除</button>
38
</a>
39
</th>
40
41
</tr>
42
{% endfor %}
43
</table>
44
</div>
45
</body>
46
</html>
47
48
49
50
#==================================================我是华丽的分割线
51
from django.shortcuts import render,redirect
52
53
from app01 import models
54
# Create your views here.
55
56
57
def index(request):
58
#从数据库取出来的数据
59
book_list=models.Book.objects.all()
60
return render(request,"index.html",{"book_list":book_list})
61
62
63
#删除
64
def deltitle(request,id):
65
models.Book.objects.filter(nid=id).delete()
66
return redirect("/index/")
67
68
#添加
69
def add(request):
70
if request.method=="POST":
71
name=request.POST.get("name")
72
bookname = request.POST.get("bookname")
73
author=request.POST.get("author")
74
time=request.POST.get("time")
75
price=request.POST.get("price")
76
models.Book.objects.create(nid=name,title=bookname,author=author,publishDate=time,price=price)
77
return redirect("/index/")
78
return render(request,"add.html")
添加
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">编号</label>
<input type="text" class="form-control" id="exampleInputEmail1" name="name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">书名</label>
<input type="text" class="form-control" id="exampleInputPassword1" name="bookname">
</div>
<div class="form-group">
<label for="exampleInputPassword1">作者</label>
<input type="text" class="form-control" id="exampleInputPassword1" name="author">
</div>
<div class="form-group">
<label for="exampleInputPassword1">时间</label>
<input type="date" class="form-control" id="exampleInputPassword1" name="time">
</div>
<div class="form-group">
<label for="exampleInputPassword1">价格</label>
<input type="text" class="form-control" id="exampleInputPassword1" name="price">
</div>
<div>
<a href="/add/"><button>提交</button></a>
</div>
</form>
</body>
</html>
35
1
2
<html lang="en">
3
<head>
4
<meta charset="UTF-8">
5
<title>Title</title>
6
</head>
7
<body>
8
<form action="" method="post">
9
{% csrf_token %}
10
<div class="form-group">
11
<label for="exampleInputEmail1">编号</label>
12
<input type="text" class="form-control" id="exampleInputEmail1" name="name">
13
</div>
14
<div class="form-group">
15
<label for="exampleInputPassword1">书名</label>
16
<input type="text" class="form-control" id="exampleInputPassword1" name="bookname">
17
</div>
18
<div class="form-group">
19
<label for="exampleInputPassword1">作者</label>
20
<input type="text" class="form-control" id="exampleInputPassword1" name="author">
21
</div>
22
<div class="form-group">
23
<label for="exampleInputPassword1">时间</label>
24
<input type="date" class="form-control" id="exampleInputPassword1" name="time">
25
</div>
26
<div class="form-group">
27
<label for="exampleInputPassword1">价格</label>
28
<input type="text" class="form-control" id="exampleInputPassword1" name="price">
29
</div>
30
<div>
31
<a href="/add/"><button>提交</button></a>
32
</div>
33
</form>
34
</body>
35
</html>
输出结果:

logging
通过logging可以查看翻译成的sql语句
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
17
1
LOGGING = {
2
'version': 1,
3
'disable_existing_loggers': False,
4
'handlers': {
5
'console':{
6
'level':'DEBUG',
7
'class':'logging.StreamHandler',
8
},
9
},
10
'loggers': {
11
'django.db.backends': {
12
'handlers': ['console'],
13
'propagate': True,
14
'level':'DEBUG',
15
},
16
}
17
}
示例:把上面的logging放入settings.py里面

当前端添加数据放入数据库时会进行数据库的操作,这样可以清晰的看到数据库做了什么操作了

注意事项:
1、 表的名称myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称
2、id
字段是自动添加的
3、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
4、这个例子中的CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
5、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py
所在应用的名称。
6、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None
字段选项
每个字段有一些特有的参数,例如,CharField需要max_length参数来指定
VARCHAR
数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我只简单介绍一些最常用的:(1)null
如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
(1)blank
如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
(2)default
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
(3)primary_key
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。
(4)unique
如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
(5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices 中的选项。
这是一个关于 choices 列表的例子:
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
)
每个元组中的第一个元素,是存储在数据库中的值;第二个元素是在管理界面或 ModelChoiceField 中用作显示的内容。 在一个给定的 model 类的实例中,想得到某个 choices 字段的显示值,就调用 get_FOO_display 方法(这里的 FOO 就是 choices 字段的名称 )。例如:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'
56
1
(1)null
2
3
如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
4
5
(1)blank
6
7
如果为True,该字段允许不填。默认为False。
8
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
9
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
10
11
(2)default
12
13
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
14
15
(3)primary_key
16
17
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
18
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
19
否则没必要设置任何一个字段的primary_key=True。
20
21
(4)unique
22
23
如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
24
25
(5)choices
26
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices 中的选项。
27
28
这是一个关于 choices 列表的例子:
29
30
YEAR_IN_SCHOOL_CHOICES = (
31
('FR', 'Freshman'),
32
('SO', 'Sophomore'),
33
('JR', 'Junior'),
34
('SR', 'Senior'),
35
('GR', 'Graduate'),
36
)
37
每个元组中的第一个元素,是存储在数据库中的值;第二个元素是在管理界面或 ModelChoiceField 中用作显示的内容。 在一个给定的 model 类的实例中,想得到某个 choices 字段的显示值,就调用 get_FOO_display 方法(这里的 FOO 就是 choices 字段的名称 )。例如:
38
39
from django.db import models
40
41
class Person(models.Model):
42
SHIRT_SIZES = (
43
('S', 'Small'),
44
('M', 'Medium'),
45
('L', 'Large'),
46
)
47
name = models.CharField(max_length=60)
48
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
49
50
51
>>> p = Person(name="Fred Flintstone", shirt_size="L")
52
>>> p.save()
53
>>> p.shirt_size
54
'L'
55
>>> p.get_shirt_size_display()
56
'Large'
一旦你建立好数据模型之后,django会自动生成一套数据库抽象的API,可以让你执行关于表记录的增删改查的操作。
添加表记录
普通字段
1.添加数据库的两种方式:
from django.shortcuts import render,redirect
from app01 import models
# Create your views here.
def index(request):
#从数据库取出来的数据
book_list=models.Book.objects.all()
return render(request,"index.html",{"book_list":book_list})
def deltitle(request,id):
models.Book.objects.filter(nid=id).delete()
return redirect("/index/")
def add(request):
if request.method=="POST":
name=request.POST.get("name")
bookname = request.POST.get("bookname")
author=request.POST.get("author")
time=request.POST.get("time")
price=request.POST.get("price")
'''
添加数据库的两种方式
'''
#方式一:
# models.Book.objects.create(nid=name,title=bookname,author=author,publishDate=time,price=price)
# 方式二
book_obj=models.Book(nid=name,title=bookname,author=author,publishDate=time,price=price)
book_obj.save()
return redirect("/index/")
return render(request,"add.html")
35
1
from django.shortcuts import render,redirect
2
3
from app01 import models
4
# Create your views here.
5
6
7
def index(request):
8
#从数据库取出来的数据
9
book_list=models.Book.objects.all()
10
return render(request,"index.html",{"book_list":book_list})
11
12
13
14
def deltitle(request,id):
15
models.Book.objects.filter(nid=id).delete()
16
return redirect("/index/")
17
18
19
def add(request):
20
if request.method=="POST":
21
name=request.POST.get("name")
22
bookname = request.POST.get("bookname")
23
author=request.POST.get("author")
24
time=request.POST.get("time")
25
price=request.POST.get("price")
26
'''
27
添加数据库的两种方式
28
'''
29
#方式一:
30
# models.Book.objects.create(nid=name,title=bookname,author=author,publishDate=time,price=price)
31
# 方式二
32
book_obj=models.Book(nid=name,title=bookname,author=author,publishDate=time,price=price)
33
book_obj.save()
34
return redirect("/index/")
35
return render(request,"add.html")
2.修改数据库的两种方式
from django.shortcuts import render ,HttpResponse,redirect
from app01 import models
# Create your views here.
def index(request):
# 从数据库取出所有书籍对象
bookList=models.Book.objects.all() # QuerySet数据类型 [bookObj1,.....]
return render(request,"index.html",{"bookList":bookList})
def delBook(request,id):
models.Book.objects.filter(nid=id).delete()
return redirect("/index/")
def editBook(request):
if request.method=="POST":
id=request.POST.get("book_id")
# 修改方式1:save(效率低)
# book_obj=models.Book.objects.filter(nid=id)[0]
# book_obj.title="东京不太热"
# book_obj.save()
# 修改方式2:
title=request.POST.get("title")
author=request.POST.get("author")
pubDate=request.POST.get("pubDate")
price=request.POST.get("price")
models.Book.objects.filter(nid=id).update(title=title,author=author,publishDate=pubDate,price=price)
return redirect("/index/")
id = request.GET.get("book_id")
print("id", id)
edit_book=models.Book.objects.filter(nid=id)[0] # [obj1,]
return render(request,"edit.html",{"edit_book":edit_book})
51
1
from django.shortcuts import render ,HttpResponse,redirect
2
3
from app01 import models
4
5
# Create your views here.
6
7
def index(request):
8
9
# 从数据库取出所有书籍对象
10
11
bookList=models.Book.objects.all() # QuerySet数据类型 [bookObj1,.....]
12
13
14
return render(request,"index.html",{"bookList":bookList})
15
16
17
def delBook(request,id):
18
19
models.Book.objects.filter(nid=id).delete()
20
21
return redirect("/index/")
22
23
24
def editBook(request):
25
26
if request.method=="POST":
27
id=request.POST.get("book_id")
28
29
# 修改方式1:save(效率低)
30
# book_obj=models.Book.objects.filter(nid=id)[0]
31
# book_obj.title="东京不太热"
32
# book_obj.save()
33
34
# 修改方式2:
35
title=request.POST.get("title")
36
author=request.POST.get("author")
37
pubDate=request.POST.get("pubDate")
38
price=request.POST.get("price")
39
40
41
models.Book.objects.filter(nid=id).update(title=title,author=author,publishDate=pubDate,price=price)
42
43
44
return redirect("/index/")
45
46
id = request.GET.get("book_id")
47
print("id", id)
48
edit_book=models.Book.objects.filter(nid=id)[0] # [obj1,]
49
50
51
return render(request,"edit.html",{"edit_book":edit_book})
外键字段
# 一对多的添加
# 方式一
# models.Publish.objects.create(name="五道口职业技术出版社",addr="北京")
# models.Book.objects.create(title="东京有点热",publishdate="2017-11-11",price=99,publish_id=1)
# return HttpResponse("OK")
# 方式二
# pubobj=models.Publish.objects.filter(name="五道口职业技术出版社")[0]
# models.Book.objects.create(title="东京不太热",publishdate="2017-11-11",price=99,publish=pubobj)
# print(pubobj.addr)
10
1
# 一对多的添加
2
# 方式一
3
# models.Publish.objects.create(name="五道口职业技术出版社",addr="北京")
4
# models.Book.objects.create(title="东京有点热",publishdate="2017-11-11",price=99,publish_id=1)
5
# return HttpResponse("OK")
6
# 方式二
7
# pubobj=models.Publish.objects.filter(name="五道口职业技术出版社")[0]
8
# models.Book.objects.create(title="东京不太热",publishdate="2017-11-11",price=99,publish=pubobj)
9
# print(pubobj.addr)
10
示例:
#models.py
from django.db import models
# Create your models here.
class Book(models.Model):
title=models.CharField(max_length=32)
publishdate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey("Publish") #建立一对多的表关系
class Publish(models.Model):
name=models.CharField(max_length=32)
addr=models.CharField(max_length=32)
# 一对多的添加
# 方式一
# models.Publish.objects.create(name="五道口职业技术出版社",addr="北京")
# models.Book.objects.create(title="东京有点热",publishdate="2017-11-11",price=99,publish_id=1)
# return HttpResponse("OK")
# 方式二
# pubobj=models.Publish.objects.filter(name="五道口职业技术出版社")[0] # 关联的出版社对象
# models.Book.objects.create(title="东京不太热",publishdate="2017-11-11",price=99,publish=pubobj)
# print(pubobj.addr)
30
1
#models.py
2
3
from django.db import models
4
5
# Create your models here.
6
7
8
class Book(models.Model):
9
title=models.CharField(max_length=32)
10
publishdate=models.DateField()
11
price=models.DecimalField(max_digits=5,decimal_places=2)
12
publish=models.ForeignKey("Publish") #建立一对多的表关系
13
14
15
16
class Publish(models.Model):
17
name=models.CharField(max_length=32)
18
addr=models.CharField(max_length=32)
19
20
# 一对多的添加
21
# 方式一
22
# models.Publish.objects.create(name="五道口职业技术出版社",addr="北京")
23
# models.Book.objects.create(title="东京有点热",publishdate="2017-11-11",price=99,publish_id=1)
24
# return HttpResponse("OK")
25
# 方式二
26
# pubobj=models.Publish.objects.filter(name="五道口职业技术出版社")[0] # 关联的出版社对象
27
# models.Book.objects.create(title="东京不太热",publishdate="2017-11-11",price=99,publish=pubobj)
28
# print(pubobj.addr)
29
30
输出结果:

多对多字段
bookobj=models.Book.objects.create(title="红楼梦",author="alex",publish="东莞出版社",publishdate="2017-10-27",price=99,publish_contrast_id=2)
alex_obj=models.Author.objects.filter(name="alex")[0]
print(alex_obj)
print(bookobj.authorlist)
# authorLish=models.Author.objects.all()
bookobj.authorlist.add(alex_obj)
6
1
bookobj=models.Book.objects.create(title="红楼梦",author="alex",publish="东莞出版社",publishdate="2017-10-27",price=99,publish_contrast_id=2)
2
alex_obj=models.Author.objects.filter(name="alex")[0]
3
print(alex_obj)
4
print(bookobj.authorlist)
5
# authorLish=models.Author.objects.all()
6
bookobj.authorlist.add(alex_obj)
1、添加多对多的关系
book_obj.authorlist.add(alex_obj,egon_obj) #将某个特定的 model 对象添加到被关联对象集合中。
book_obj.authorlist.add(*authorList) #通过某个特定的model集合对象添加到被关联对象集合中
2
1
book_obj.authorlist.add(alex_obj,egon_obj) #将某个特定的 model 对象添加到被关联对象集合中。
2
book_obj.authorlist.add(*authorList) #通过某个特定的model集合对象添加到被关联对象集合中
2、解除多对多的关系
book_obj.authors.remove() # 将某个特定的对象从被关联对象集合中去除。
book_obj.authors.remove(*[])
3
1
book_obj.authors.remove() # 将某个特定的对象从被关联对象集合中去除。
2
book_obj.authors.remove(*[])
3
3、清空多对多的关系
book_obj.authors.clear()
1
1
book_obj.authors.clear()
查询表记录
查询相关API
<1> all(): 查询所有结果
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
如果符合筛选条件的对象超过一个或者没有都会抛出错误。
<4> getlist(**kwargs) 返回一个列表
<5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
<4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
model的实例化对象,而是一个可迭代的字典序列
<9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
<6> order_by(*field): 对查询结果排序
<7> reverse(): 对查询结果反向排序
<8> distinct(): 从返回结果中剔除重复纪录
<10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
<11> first(): 返回第一条记录
<12> last(): 返回最后一条记录
<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
<14> only
<15> defer
33
1
<1> all(): 查询所有结果
2
3
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
4
5
<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
6
如果符合筛选条件的对象超过一个或者没有都会抛出错误。
7
<4> getlist(**kwargs) 返回一个列表
8
9
<5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
10
11
<4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
12
model的实例化对象,而是一个可迭代的字典序列
13
14
<9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
15
16
<6> order_by(*field): 对查询结果排序
17
18
<7> reverse(): 对查询结果反向排序
19
20
<8> distinct(): 从返回结果中剔除重复纪录
21
22
<10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
23
24
<11> first(): 返回第一条记录
25
26
<12> last(): 返回最后一条记录
27
28
<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
29
30
<14> only
31
32
<15> defer
33
注意:一定区分object与querySet的区别 !!!
示例:
def query(request):
# 查询方法API:
#1 all: models.表名.objects.all()
book_all=models.Book.objects.all() # 结果是querySet集合 [model对象,....]
#print(book_all) # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
# 2 filter: models.表名.objects.filter() # 结果是querySet集合 [model对象,....]
# ret1=models.Book.objects.filter(author="yuan") # # <QuerySet [<Book: 追风筝的人>, <Book: asd>]>
#ret2=models.Book.objects.filter(nid=1) # <QuerySet [<Book: yuan>]>
# ret2=models.Book.objects.filter(author="yuan",price=123) # <QuerySet [<Book: yuan>]>
# print(ret2)
# 3 get models.表名.objects.get() # model对象
# ret3=models.Book.objects.get(author="yuan")
# print(ret3.price)
# exclude : 排除条件
# ret4=models.Book.objects.exclude(author="yuan")
# print(ret4)
# values方法
# ret=models.Book.objects.filter(author="yuan").values("title","price")
# print(ret)# <QuerySet [{'title': '追风筝的人', 'price': Decimal('99.00')}, {'title': 'asd', 'price': Decimal('123.00')}]>
# ret = models.Book.objects.filter(author="yuan").values_list("title", "price")
# print(ret) # <QuerySet [('追风筝的人', Decimal('99.00')), ('asd', Decimal('123.00'))]>
# ret=models.Book.objects.filter(author="yuan").values("author").distinct()
# print(ret)
# count方法
# ret=models.Book.objects.filter(author="yuan").count()
# print(ret)
# first 方法
# ret = models.Book.objects.all().first()
# print(ret)
# exists方法
# if models.Book.objects.all().exists():
# print("exists")
# else:
# print("nothing")
ret=models.Book.objects.filter(price__gt=100)
ret=models.Book.objects.filter(price__gte=99) # 大于等于
#ret=models.Book.objects.filter(publishDate__year=2017,publishDate__month=10)
#ret=models.Book.objects.filter(author__startswith="张")
print(ret)
return HttpResponse("OK")
62
1
def query(request):
2
# 查询方法API:
3
4
5
#1 all: models.表名.objects.all()
6
7
book_all=models.Book.objects.all() # 结果是querySet集合 [model对象,....]
8
#print(book_all) # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
9
10
# 2 filter: models.表名.objects.filter() # 结果是querySet集合 [model对象,....]
11
12
# ret1=models.Book.objects.filter(author="yuan") # # <QuerySet [<Book: 追风筝的人>, <Book: asd>]>
13
#ret2=models.Book.objects.filter(nid=1) # <QuerySet [<Book: yuan>]>
14
# ret2=models.Book.objects.filter(author="yuan",price=123) # <QuerySet [<Book: yuan>]>
15
# print(ret2)
16
17
# 3 get models.表名.objects.get() # model对象
18
19
# ret3=models.Book.objects.get(author="yuan")
20
# print(ret3.price)
21
22
23
# exclude : 排除条件
24
# ret4=models.Book.objects.exclude(author="yuan")
25
# print(ret4)
26
27
# values方法
28
# ret=models.Book.objects.filter(author="yuan").values("title","price")
29
# print(ret)# <QuerySet [{'title': '追风筝的人', 'price': Decimal('99.00')}, {'title': 'asd', 'price': Decimal('123.00')}]>
30
31
# ret = models.Book.objects.filter(author="yuan").values_list("title", "price")
32
# print(ret) # <QuerySet [('追风筝的人', Decimal('99.00')), ('asd', Decimal('123.00'))]>
33
34
# ret=models.Book.objects.filter(author="yuan").values("author").distinct()
35
# print(ret)
36
37
# count方法
38
# ret=models.Book.objects.filter(author="yuan").count()
39
# print(ret)
40
41
# first 方法
42
# ret = models.Book.objects.all().first()
43
# print(ret)
44
45
# exists方法
46
# if models.Book.objects.all().exists():
47
# print("exists")
48
# else:
49
# print("nothing")
50
51
52
53
ret=models.Book.objects.filter(price__gt=100)
54
ret=models.Book.objects.filter(price__gte=99) # 大于等于
55
56
#ret=models.Book.objects.filter(publishDate__year=2017,publishDate__month=10)
57
#ret=models.Book.objects.filter(author__startswith="张")
58
59
60
print(ret)
61
return HttpResponse("OK")
62
******重点注意QuerySet对象和objcet对象
Django ORM用到三个类:Manager、QuerySet、Model。Manager定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类,定义自己的manager,增加表级方法;QuerySet:Manager类的一些方法会返回QuerySet实例,QuerySet是一个可遍历结构,包含一个或多个元素,每个元素都是一个Model 实例,它里面的方法也是表级方法,前面说了,Django给我们提供了增加表级方法的途径,那就是自定义manager类,而不是自定义QuerySet类,一般的我们没有自定义QuerySet类的必要;django.db.models模块中的Model类,我们定义表的model时,就是继承它,它的功能很强大,通过自定义model的instance可以获取外键实体等,它的方法都是记录级方法(都是实例方法,貌似无类方法),不要在里面定义类方法,比如计算记录的总数,查看所有记录,这些应该放在自定义的manager类中
queryset对象
pubobj=models.Book.objects.all() #这是queryset对象通过queryset调用API的方法
1
1
pubobj=models.Book.objects.all() #这是queryset对象通过queryset调用API的方法
object对象
pubobj=models.Book.objects.filter(title="东京有点热").first() #拿到关联字段的对象
print(pubobj.price) #这样就可以通过.来调用字段获取字段的信息
2
1
pubobj=models.Book.objects.filter(title="东京有点热").first() #拿到关联字段的对象
2
print(pubobj.price) #这样就可以通过.来调用字段获取字段的信息
输出结果:

数据库表查询
表结构
from django.db import models
# Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5, decimal_places=2)
wordNum=models.IntegerField(default=0)
readNum=models.IntegerField(default=0)
publish=models.ForeignKey("Publish",related_name="bookList") #一对多关系
authorlist=models.ManyToManyField("Author",related_name="bookList") # 多对多的关系,自动创建关系表
def __str__(self):
return self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
def __str__(self):
return self.name
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
author_detail=models.OneToOneField("AuthorDetail") #一对一关系
def __str__(self):
return self.name
class AuthorDetail(models.Model):
tel=models.IntegerField()
addr=models.CharField(max_length=32)
45
1
from django.db import models
2
3
# Create your models here.
4
5
6
class Book(models.Model):
7
nid = models.AutoField(primary_key=True)
8
title = models.CharField(max_length=32)
9
publishDate = models.DateField()
10
price = models.DecimalField(max_digits=5, decimal_places=2)
11
wordNum=models.IntegerField(default=0)
12
readNum=models.IntegerField(default=0)
13
14
15
publish=models.ForeignKey("Publish",related_name="bookList") #一对多关系
16
17
authorlist=models.ManyToManyField("Author",related_name="bookList") # 多对多的关系,自动创建关系表
18
19
def __str__(self):
20
21
return self.title
22
23
24
class Publish(models.Model):
25
name = models.CharField(max_length=32)
26
addr = models.CharField(max_length=32)
27
28
def __str__(self):
29
return self.name
30
31
class Author(models.Model):
32
name=models.CharField(max_length=32)
33
age=models.IntegerField()
34
author_detail=models.OneToOneField("AuthorDetail") #一对一关系
35
def __str__(self):
36
return self.name
37
38
class AuthorDetail(models.Model):
39
tel=models.IntegerField()
40
addr=models.CharField(max_length=32)
41
42
43
44
45
一对一关系的查询
#一对一查询
#正向查询 按字段
# 一对一关系查询
# # 查询egon的手机号
author_obj=models.Author.objects.filter(name="egon").first()
print(author_obj.author_detail.tel)
#反向查询 按表名
#查询手机号为456的作者的姓名
author_de=models.AuthorDetail.objects.filter(tel="456").first()
print(author_de)
print(author_de.author.name)
12
1
#一对一查询
2
#正向查询 按字段
3
# 一对一关系查询
4
# # 查询egon的手机号
5
author_obj=models.Author.objects.filter(name="egon").first()
6
print(author_obj.author_detail.tel)
7
#反向查询 按表名
8
#查询手机号为456的作者的姓名
9
author_de=models.AuthorDetail.objects.filter(tel="456").first()
10
print(author_de)
11
print(author_de.author.name)
12
一对多关系的查询
# 一对多的查询
# 查询linux这本书的出版社的地址?
#正向查询 按字段
book_obj=models.Book.objects.get(title="linux") #get方式
print(book_obj)
print(book_obj.publish.addr)
或者
book_obj=models.Book.objects.filter(title="linux").first() #filter方式
print(book_obj)
print(book_obj.publish.addr)
#反向查询
# 人民出版社出版过的书籍的名字
#按related_name别名来查询
publish_obj=models.Publish.objects.filter(name="人民出版社").first()
print(publish_obj.bookList.all())
20
1
# 一对多的查询
2
# 查询linux这本书的出版社的地址?
3
#正向查询 按字段
4
book_obj=models.Book.objects.get(title="linux") #get方式
5
print(book_obj)
6
print(book_obj.publish.addr)
7
或者
8
book_obj=models.Book.objects.filter(title="linux").first() #filter方式
9
print(book_obj)
10
print(book_obj.publish.addr)
11
#反向查询
12
# 人民出版社出版过的书籍的名字
13
#按related_name别名来查询
14
publish_obj=models.Publish.objects.filter(name="人民出版社").first()
15
print(publish_obj.bookList.all())
16
17
18
19
20
多对多关系的查询
# 多对多的查询
#正向查询 按字段
# 查询追风筝的人的所有作者的姓名和年龄
book_obj=models.Book.objects.filter(title="python红宝书")[0]
authorlist=book_obj.authorlist.all() #与这本书关联的所有作者对象,集合对象 <QuerySet [<Author: alex>, <Author: egon>, <Author: eva>]>
print(authorlist)
print(authorlist.values("name"))
#反向查询 按related_name别名查询
# 查询yuan出版过的所有书籍的名字和价格
author_yuan=models.Author.objects.get(name="alex")
# print(author_yuan.Book_set.all()) # 与这个作者关联的所有书籍对象
print(author_yuan.bookList.all().values("title","price"))
12
1
# 多对多的查询
2
#正向查询 按字段
3
# 查询追风筝的人的所有作者的姓名和年龄
4
book_obj=models.Book.objects.filter(title="python红宝书")[0]
5
authorlist=book_obj.authorlist.all() #与这本书关联的所有作者对象,集合对象 <QuerySet [<Author: alex>, <Author: egon>, <Author: eva>]>
6
print(authorlist)
7
print(authorlist.values("name"))
8
#反向查询 按related_name别名查询
9
# 查询yuan出版过的所有书籍的名字和价格
10
author_yuan=models.Author.objects.get(name="alex")
11
# print(author_yuan.Book_set.all()) # 与这个作者关联的所有书籍对象
12
print(author_yuan.bookList.all().values("title","price"))
双下划线之单表查询
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
startswith,istartswith, endswith, iendswith
11
1
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
2
3
models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
4
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
5
6
models.Tb1.objects.filter(name__contains="ven")
7
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
8
9
models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
10
11
startswith,istartswith, endswith, iendswith
示例:
双下划线之跨表查询
1.一对一关系的查询
# 查询linux这本书的出版社的地址?
#正向查询 #按字段
print(models.Book.objects.filter(title="python红宝书").values("publish__addr")) #通过__来进行跨表查询
# 查询人民出版社出版过的所有书籍的名字与价格
#反向查询 按related_name别名查询
print(models.Publish.objects.filter(name="人民出版社").values("bookList__title","bookList__price"))
7
1
# 查询linux这本书的出版社的地址?
2
#正向查询 #按字段
3
print(models.Book.objects.filter(title="python红宝书").values("publish__addr")) #通过__来进行跨表查询
4
# 查询人民出版社出版过的所有书籍的名字与价格
5
#反向查询 按related_name别名查询
6
print(models.Publish.objects.filter(name="人民出版社").values("bookList__title","bookList__price"))
7
2.多对多关系的查询
#查询egon出过的所有书籍的名字(多对多)
#反向 按related_name别名查询
print(models.Author.objects.filter(name="egon").values("bookList__title"))
#正向 按照字段查询
#查询linux是哪个作者写的
ret=models.Book.objects.filter(title="linux").values("authorlist__name")
print(ret)
7
1
#查询egon出过的所有书籍的名字(多对多)
2
#反向 按related_name别名查询
3
print(models.Author.objects.filter(name="egon").values("bookList__title"))
4
#正向 按照字段查询
5
#查询linux是哪个作者写的
6
ret=models.Book.objects.filter(title="linux").values("authorlist__name")
7
print(ret)
3.一对一关系的查询
#正向查询 #按字段
#作者为egon的手机号
ret=models.Author.objects.filter(name="egon").values("author_detail__tel")
print(ret)
#反向查询 按表名
#手机号为456的作者
ret=models.AuthorDetail.objects.filter(tel="456").values("author__name")
print(ret)
12
1
#正向查询 #按字段
2
#作者为egon的手机号
3
ret=models.Author.objects.filter(name="egon").values("author_detail__tel")
4
print(ret)
5
6
#反向查询 按表名
7
#手机号为456的作者
8
ret=models.AuthorDetail.objects.filter(tel="456").values("author__name")
9
print(ret)
10
11
12
4.多表联合查询
# 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
方法一:反向查询
ret=models.AuthorDetail.objects.filter(tel__startswith="151").first() #__startswith 以内容开头
print(ret)
print(ret.author.bookList.all().values("title","publish__name"))
方法二:
# 方法2正向查询
ret=models.Book.objects.filter(authorlist__author_detail__tel__startswith="151").values("title","publish__name")
print(ret)
9
1
# 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
2
方法一:反向查询
3
ret=models.AuthorDetail.objects.filter(tel__startswith="151").first() #__startswith 以内容开头
4
print(ret)
5
print(ret.author.bookList.all().values("title","publish__name"))
6
方法二:
7
# 方法2正向查询
8
ret=models.Book.objects.filter(authorlist__author_detail__tel__startswith="151").values("title","publish__name")
9
print(ret)
聚合查询与分组查询
导入聚合函数的和分组查询的模块
from django.db.models import Avg,Sum,Count,Max,Min
1
1
from django.db.models import Avg,Sum,Count,Max,Min
聚合:aggregate(*args, **kwargs)
聚合函数:aggregate
# 查询所有图书的价格和
ret=models.Book.objects.all().aggregate(priceSum=Sum("price")) #pruceSum自定义名字,如果没加的话会默认加上名字
print(ret)
输出结果:
'''
{'priceSum': Decimal('166.00')}
'''
9
1
聚合函数:aggregate
2
# 查询所有图书的价格和
3
ret=models.Book.objects.all().aggregate(priceSum=Sum("price")) #pruceSum自定义名字,如果没加的话会默认加上名字
4
print(ret)
5
输出结果:
6
'''
7
{'priceSum': Decimal('166.00')}
8
9
'''
分组:annotate()
# 分组函数 annote函数
# 查询每一本书的作者个数
book_list=models.Book.objects.all().annotate(c=Count("authorlist__name"))
for book_obj in book_list:
print(book_obj.c)
7
1
# 分组函数 annote函数
2
3
# 查询每一本书的作者个数
4
5
book_list=models.Book.objects.all().annotate(c=Count("authorlist__name"))
6
for book_obj in book_list:
7
print(book_obj.c)
F查询与Q查询
F查询
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
示例:from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def login(request):
return render(request,"login.html")
def index(request):
obj=models.Admin.objects.filter(commentNumb__gt=200).values("id") #可以通过整数来定义查询条件但是却不能按相同方法比较数据库中的字段
print(obj)
return HttpResponse("OK")
17
1
from django.shortcuts import render,HttpResponse
2
3
from app01 import models
4
5
# Create your views here.
6
7
8
9
10
def login(request):
11
return render(request,"login.html")
12
13
14
def index(request):
15
obj=models.Admin.objects.filter(commentNumb__gt=200).values("id") #可以通过整数来定义查询条件但是却不能按相同方法比较数据库中的字段
16
print(obj)
17
return HttpResponse("OK")
解决方法:
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
#必须要导入F
from django.db.models import F,Q
def login(request):
return render(request,"login.html")
def index(request):
#查询评论数小于阅读数的字段
obj=models.Admin.objects.filter(commentNumb__lt= F('readNumb')).values("id")
# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)
#修改操作也可以使用F函数,比如将每一本书的价格提高30元:
Book.objects.all().update(price=F("price")+30)
print(obj)
return HttpResponse("OK")
25
1
from django.shortcuts import render,HttpResponse
2
3
from app01 import models
4
5
# Create your views here.
6
#必须要导入F
7
from django.db.models import F,Q
8
9
10
def login(request):
11
return render(request,"login.html")
12
13
14
def index(request):
15
#查询评论数小于阅读数的字段
16
obj=models.Admin.objects.filter(commentNumb__lt= F('readNumb')).values("id")
17
# 查询评论数大于收藏数2倍的书籍
18
Book.objects.filter(commnetNum__lt=F('keepNum')*2)
19
20
#修改操作也可以使用F函数,比如将每一本书的价格提高30元:
21
22
Book.objects.all().update(price=F("price")+30)
23
print(obj)
24
return HttpResponse("OK")
25
数据库

输出结果:可以看到输出两个

Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
from django.db.models import F,Q
def login(request):
return render(request,"login.html")
def index(request):
# obj=models.Admin.objects.filter(commentNumb__lt= F('readNumb')).values("id")
#查询name=chenyang and name=egon的书籍
obj = models.Admin.objects.filter(Q(name="chenyang")|Q(name="egon")).values("title")
print(obj)
return HttpResponse("OK")
x
1
from django.shortcuts import render,HttpResponse
2
3
from app01 import models
4
5
# Create your views here.
6
from django.db.models import F,Q
7
8
9
def login(request):
10
return render(request,"login.html")
11
12
13
def index(request):
14
# obj=models.Admin.objects.filter(commentNumb__lt= F('readNumb')).values("id")
15
#查询name=chenyang and name=egon的书籍
16
obj = models.Admin.objects.filter(Q(name="chenyang")|Q(name="egon")).values("title")
17
print(obj)
18
return HttpResponse("OK")
数据库

输出结果:

你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:
bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

