Django之orm模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# 默认使用sqlite
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }

# 修改使用mysql
# 导入pymysql模块
import pymysql

pymysql.install_as_MySQLdb()

# 配置以下代码
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db_name',
'HOST': 'x.x.x.x',
'PORT': '3306',
'USER': 'user',
'PASSWORD': 'password',
}
}

from django.db import models

# Create your models here.
# ORM 对象--关系--映射

# 单表操作
# 比如创建一个图书表

# 创建模型
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
state = models.BooleanField()
pub_date = models.DateField()
price = models.DecimalField(max_digits=5, decimal_places=2) # 最大999.99
publish = models.CharField(max_length=32)

"""
字段
AutoField
自定义一个主键 my_id = models.AutoField(primary_key=True)

CharField
字符串字段 用于较短的字符串
CharField 必须有一个参数max_length 允许的最大字符数
title = models.CharField(max_length=32)

IntegerField
一个整数
sid = models.IntegerField

FloatFieldDecimalField
一个浮点数 必须提供两个参数
max_digits 总位数 不包括小数点和符号
decimal_places 小数位数
price = models.DecimalField(max_digits=5, decimal_places=2) # 最大999.99

BooleanField
一个布尔值True或False

TextField
大容量的文本字段

EmailField
带校验Email是否合法的CharField 不需要参数max_length

DateField
一个日期字段
可选参数
Argument 描述
auto_now 当对象被保存时 自动将改字段的值设置为当前时间
auto_now_add 当对象首次被创建时 自动将该字段的值设置为当前时间

DateTimeField
一个时间字段
可选参数
同DateField

FileField
一个文件上传字段
必须提供参数 upload_to 用于保存上传文件的本地系统路径

ImageField
类似于FileField 不过要校验上传对象是否是合法图片
可选参数
height_field
width_field
加这两个参数 则图片将按提供的宽度和高度保存

注意 要在model中使用FileField 和ImageField 需要以下步骤
setting文件中定义一个完整路径给MEDIA_ROOT 以便于django在此保存上传文件
同时要定义 MEDIA_URL 作为该目录的公共 URL

在model中添加FileField 和ImageField 确认定义upload_to 选项 告诉django使用MEDIA_ROOT
的那个子目录保存上传文件 数据库中保存文件路径

URLField
用于保存URL 加参数verify_exists 默认为True 检查URL是否存在也就是URL是否有效且没有返回403响应

NullBooleanField
类似于BooleanField 不允许为空

SlugField
短签 只包含字母 数字 下划线_ 连字符.

XMLField
一个校验值是否为合法XML的TextField 必须提供参数schema_path
用于校验文本的 RelaxNG schema 的文件系统路径

FilePathField
可选项目 某个指定目录的文件名 支持三个特殊参数 第一个必须
path 必需参数 一个目录的绝对路径
math
recursive

IPAddressField
一个字符串形式的IP地址 "1.2.4.8"

CommaSeparatedIntegerField
用于存放逗号分隔的整数值 类似于CharField 必须提供maxlength参数

"""

"""
参数

null
如果为True django 将用null存数据库中空值 默认为False

blank
如果为True 该字段允许不填 默认为False
与null区别
null是数据库范畴
blank是数据验证范畴
如果一个字段blank=True 表单验证允许该字段是空值 反之不允许

default
字段的默认值 可以是一个值或者可调用对象

primary key
如果为True 那么该字段 就是模型的主键 如果没有指定任何字段
django 就会自动添加一个IntegerField字段作为主键

unique
如果为True 这个数据自动的值在整张表必须是唯一的

choices
由二元组组成一个可迭代对象(如 列表 元组)

"""

# 通过以下两条数据库迁移命令更新创建表
# python manage.py makemigrations
# python manage.py migrate

# 新增记录
# book_obj = Book.objects.create(
# title='Python从入门到精通',
# state=True,
# price=100,
# publish='XXX出版社',
# pub_date='2016-12-10'
# )
#
# book_obj2 = Book(
# title='Php从入门到实战',
# state=True,
# price=90,
# publish='YYY出版社',
# pub_date='2017-12-10'
# )
# book_obj2.save()

# 删除记录
def delbook(request, did=None):
# delete()方法由QuerySet调用
# model对象也有delete() 方法
# Book.objects.filter(id=did).delete()
Book.objects.get(id=did).delete()
return redirect(reverse("app01:books"))

更新记录
data = request.POST.dict()
del data['csrfmiddlewaretoken']
# update() 方法只能由QuerySet调用
Book.objects.filter(id=eid).update(**data) # **将一个字典打散
return redirect(reverse("app01:books"))

查询记录
查询所有结果 由object调用 返回QuerySet对象
ret = Book.objects.all()

查询所有筛选条件匹配的对象 由object调用 返回的是QuerySet
Book.objects.filter(title='Linux')

查询筛选条件匹配的对象 返回结果有且只有一个
如果匹配对象超过一个或者没有将抛出错误
由object调用 返回的是models对象
Book.objects.get(title='Java')

查询所有筛选条件不匹配的对象 由object调用 返回的是QuerySet
Book.objects.exclude(price=100)

对查询结果排序 'id' 升序 '-id' 降序 由QuerySet调用 返回的是QuerySet
Book.objects.all().order_by('-id')

对查询结果反向排序 由QuerySet调用 返回的是QuerySet
Book.objects.all().order_by('-price', '-id').reverse()

返回匹配的对象数量 由QuerySet调用 返回init
Book.objects.all().order_by('-price', '-id').count()

返回第一条记录 由QuerySet调用 返回的是models对象
Book.objects.all().order_by('-price', '-id').first()

返回最后一条记录 由QuerySet调用 返回的是models对象
Book.objects.all().order_by('-price', '-id').last()

查询对象是否包含数据 是否存在 存在True 否则False 由QuerySet调用 返回布尔值
Book.objects.filter(title='Linux入门').exists()

由QuerySet调用 返回的是QuerySet 元素是字典
Book.objects.all().values('title')

由QuerySet调用 返回的是QuerySet 元素是元组
Book.objects.all().values_list('title')

去重 由QuerySet调用 返回的是QuerySet
Book.objects.all().values_list('title').distinct()

模糊查询
价格在100 200 300
Book.objects.filter(price__in=[100,200,300])

价格大于100
Book.objects.filter(price__gt=100)

价格大于等于100
Book.objects.filter(price__gte=100)

价格小于100
Book.objects.filter(price__lt=100)

价格小于等于100
Book.objects.filter(price__lte=100)
价格在100 到 200 之间 包括100和200
Book.objects.filter(price__range=[100,200])

标题含有Python关键字 精确
Book.objects.filter(title__contains='Python')

标题含有Python关键字 不区分大小写
Book.objects.filter(title__icontains='Python')

标题以Py关键字开头 精确
Book.objects.filter(title__startswith="Py")

标题含有Python关键字 不区分大小写
Book.objects.filter(title__icontains='Python')

标题以a关键字结尾 精确
Book.objects.filter(title__endswith='a')

标题以a关键字结尾 不区分大小写
Book.objects.filter(title__iendswith='a')
查询出版日期是
2012 Book.objects.filter(pub_date__year=2012)