0%

Python|django框架入门3

django框架的学习第三弹!一起来学习让人理解困难的数据库和表单吧……

模型与数据库

Django支持各种数据库,并为这些数据库提供了统一的调用API,这些API统称为ORM框架,通过ORM框架可以实现数据库连接和读写操作

构建模型

Django中通过虚拟对象数据库(模型)来实现对目标数据库的读写操作

1.配置目标数据库信息

在项目下的setting.py进行配置

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydata',
'USER' : 'root' ,
'PASSWORD' : '1234',
'HOST' : '127.0.0.1',
'PORT':'3306',
},
}

开启mysql的服务后,用Navicat工具连接数据库并新建一个mydata的数据库

2.构建虚拟对象数据库

在app的models.py文件中以类的形式定义模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.db import models

#产品分类表
class Type(models.Model):
id = models.AutoField('序号',primary_key=True)
type_name = models.CharField('产品类型',max_length=20)

#产品信息表
class Product(models.Model):
id = models.AutoField('序号',primary_key=True)
name = models.CharField('名称',max_length=50)
weight = models.CharField('重量', max_length=20)
size = models.CharField('尺寸', max_length=20)
type = models.ForeignKey(Type, on_delete=models.CASCADE,verbose_name='产品类型')

  • 模型以类的方式进行定义,并且继承Django的models.Model类,类的命名一般以首字母大写开头
  • 模型字段以类属性进行定义,其中的常用数据类型和参数解释如下

表字段常用数据类型:

表字段 说明
models.AutoField 默认会生成一个名为id的字段并为int类型
models.CharField 字符串类型
models.BooleanField 布尔类型
models.DateField 日期(date) 类型
models.DateTimeField 日期(datetime) 类型
models.EmailField 字符串类型(正则表达式邮箱)
models.FloatField 浮点类型
models.IntegerField 整数类型

连邮箱的类型都考虑到就非常贴心了

表字段常用参数

参数 说明
Null 如为True,字段可以为空
Blank 如为True,设置在Admin站点管理中添加数据时可允许空值
primary_ key 如为True,将字段设置成主键
verbose _name 在Admin站点管理设置字段的显示名称
3.生成数据表

通过模型在目标数据库创建相应的数据表,使用下面的两个命令行即可生成数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
D:\django\mysite
(django) λ python manage.py makemigrations
Migrations for 'index':
index\migrations\0003_auto_20200405_1522.py
- Create model Product
- Create model Type
- Delete model laopo
- Add field type to product

D:\django\mysite
(django) λ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, index, sessions
Running migrations:
Applying index.0003_auto_20200405_1522... OK

D:\django\mysite
(django) λ

用Navicat查看数据库,即可发现数据表生成成功

数据表的关系

每个数据表是可以存在关联的,表与表之间有三种关系:

1.一对一

用OneToOneField构建一对一关系

1
models.ForeignKey(第一个表名, on_delete=models.CASCADE)
2.一对多

用ForeignKey构建一对多关系,这样的关系是常用的

1
models.ForeignKey(Type, on_delete=models.CASCADE,verbose_name='产品类型')
3.多对多

用ManyToManyField构建多对多关系,这种关系不常用

数据表的读写

数据表的读写操作主要实现对数据的增删改查,首先要在数据表中添加数据如图

1.工具使用

为了更好演示数据库的读写操作,以下使用PyCharm的shell模式来操作数据库,实际运用中的代码也是一样的。

在PyCharm的Terminal下开启shell模式

1
python manage.py shell
2.插入数据

(1)方法一:通过对模型Product进行操作

输入以下代码

1
2
3
4
5
6
7
>>> from index . models import *
>>> p = Product()
>>> p.name = 'black'
>>> p.weight = '111g'
>>> p.size = '255mm'
>>> p.type_id = 1
>>> p.save()

插入方式的原理:

  • 从models.py中导入模型Product
  • 对模型Product声明并实例化,生成对象p
  • 对对象p的属性进行逐一赋值
  • 完成赋值后需要对p进行保存

(2)方法二:通过ORM框架提供的API实现,使用create方法实现数据插入,常用方法

1
2
>>>from index . models import *
>>>Product.objects.create(name = 'black',weight = '111g',size = '255mm',type_id = 1)

(3)方法三:实例化时直接设置属性值

1
2
3
>>> from index . models import *
>>> p = Product(name = 'black',weight = '111g',size = '255mm',type_id = 1)
>>> p.save()
3.更新数据

数据更新的实现步骤与数据插入类似,唯一的区别是在模型实例化后,更新数据要进行数据查询

(1)方法一:通过对模型Product进行操作

1
2
3
4
>>> from index . models import *
>>> p = Product.objects.get(id = 3)
>>> p.name = 'black'
>>> p.save()

(2)方法二:通过ORM框架提供的API实现,使用update方法实现数据更新

1
2
3
4
5
6
7
8
9
from index . models import *
#更新单条数据,使用查询条件get
Product.objects.get(id=4).update(name='yellow')

#更新多条数据,使用查询条件filter以列表格式返回
Product.objects.filter(name='red').update(weight='666g')

#全表数据更新
Product.objects.update(name='yellow')
4.数据删除
1
2
3
4
5
6
7
8
#删除表中全部数据
Product.objects.all().delete()

#删除一条id为1的数据
Product.objects.get(id = 1) .delete()

#删除多条数据
Product.objects .filter (name='华为荣耀V9') .delete()

数据的删除和更新都用到了查询条件filter和查询条件get,其区别如下:

  • 查询字段必须是主键或者唯一约束的字段,并且查询的数据必须存在
  • 查询字段没有限制,只要该字段是数据表的某一字段即可,查询结果以列表的形式返回
5.数据查询

数据查询的内容是数据库操作内容最为多最为复杂的部分

常用的查询方法:

(1)全表查询

1
2
3
#数据以列表形式返回
>>> p = Product.objects.all()
>>> p[1] . name

(2)查询前5个数据

1
2
#在Django中使用Python的列表截取分解即可实现
>>> p = Product.objects.all() [:5]

(3)查询某个字段

1
2
3
#values方法,以列表形式返回数据,列表元素以字典格式表示
>>> p = Product.objects. values ('name')
>>> p[1] #[ 'name']

(4)列表表示返回数据

1
2
3
# values_ list 方法,以列表表示返回数据,列表元素以元组格式表示
>>> P = Product.objects. values_ list('name') [:3]
>>> P

(5)使用get方法查询数据

1
2
>>> p= Product. objects.get(id = 2)
>>> p.name

(6)使用filter方法查询数据,注意区分get和filter的差异

1
2
>>> p = Product. objects.filter(id = 2)
>>> p[0] .name

(7)and查询主要在filter里面添加多个查询条件

1
2
>>> p = Product. objects . filter (name='red',id=2)
>>> p

(8)or查询,需要引入Q,

1
2
3
>>> from django . db .models import Q
>>> p = Product. objects . filter(Q (name='red')|Q(id=3))
>>> p

(9)查询数据量

1
2
3
#使用count方法统计查询数据的数据量
>>> p = Product . objects . filter (name='yellow').count ()
>>> P

(10)去重查询

1
2
3
#distinct方法无须设置参数,去重方式根据values设置的字段执行
>>> p = Product.objects.values ('name').filter (name='red').distinct()
>>> P

以上均使用等值来匹配结果,若想实现其他骚操作,可以参考以下匹配符

多表查询

对多个关联的数据表进行查询,我们可以使用select_related方法实现,此处不做介绍……

表单与模型

表单是用户信息的集合,作用是实现网页上的数据交互。

用户表单是web开发的一项基本功能,django的表单功能由Form类实现,主要有两种:django.forms.Form (基础的表单功能),django.forms.ModelForm(在前者的基础上结合模型所生成的数据表单)

初识表单

1.表单在html

在html中表单由

标签实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<body>
<!--表单-->
<form action="" me thod="post">
First name: <br>
<input type="text" name=" firstname" value="Mickey">
<br><br>
<input type="submit" value=" Submit">

<!--表单-->
Last name: <br>
<input type="text" name=" lastname" value="Mouse">
<br><br>
<input type="submit" value=" Submit">
</form>
</body>
</html>

由此可知一个完整的表单有4个组成部分:提交地址,请求方式,元素控件,提交按钮

组成部分 介绍
提交地址 提交地址用于设置用户提交的表单数据应由哪个URL接收和处理,由
的属性action 决定
请求方式 请求方式用于设置表单的提交方式,通常是GET请求或POST请求,由
的属性method
元素控件 元素控件是供用户输入数据信息的输入框。由HTML的控件实现,属性type用于设置输入框的类型
提交按钮 提交按钮供用户提交数据到服务器,该按钮也是由HTML的 控件实现type=”submit”

下面以django的方式实现上述功能

2.定义表单
1
2
3
4
5
6
7
8
9
10
11
#定义ProudctForm表单对象
from django import forms
from . models import*
class ProductForm (forms. Form) :
name = forms.CharField(max_length = 20,label = '名字',)
weight = forms.CharField(max_length = 50,label = ' 重量')
size = forms.CharField(max_length = 50,label = '尺寸')

# 设置下拉框的值
choices_list = [(i + 1, v['type_ name']) for i, v in enumerate(Type.objects.values('type_ name'))]
type = forms.ChoiceField(choices=choices_list, labe1 = ' 产品类型')

在index中添加form.py,用于实现编写表单实现功能。定义了表单ProductForm。表单以类的形式表示,表单中定义了不同类型的类属性,即表单字段(类似HTML的一个控件)

3.视图实例化
1
2
3
4
5
# views.py代码,将表单ProductForm实例化并将其传递到模板中生成网页内容
from django.shortcuts import renderfrom . form import *
def index (request) :
product = ProductForm()
return render(request,'data_form.html', locals())

在views中导入ProductForm类,在视图函数中实例化生成对象product并把它传给html

4.网页显示

将对象以HTML的

的形式展示在网页上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if product.errors %}
<p>
数据出错啦,错误信息: {{ product . errors }}.
</p>
{% else %}
<form action="" method="post">
{% csrf_ token %}
<table>
{{ product.as_ table }}
</table>
<input type="submit" value=" 提交">
</form>

{% endif %}
</body>
</html>

最终实现效果:

表单定义

1.内置表单字段
字段 说明
BooleanField 复选框,如果字段带有required=True,复选框被勾选上
CharField 参数max_ length和min_ length分 别设置输入长度
ChoiceField 下拉框,参数choices设置数据内容
DateField 文本框,具有验证日期格式的功能,参数input_ formats设置日期格
EmailField 文本框,验证输入数据是否为合法的邮箱地址
FileField 文件上传功能,参数max_ length和allow empty_ file分别用于设置文件名的最大长度和文件内容是否为空
ImageField 验证文件是否为Pillow库可识别的图像格式
IntegerField 验证数据是否为整型
URLField 验证数据是否为有效的URL地址
2.表单字段参数
参数 说明
Required 输入数据是否为空,默认值为True
Widget 设置HTMI控件的样式
Label 用于生成Label标签或显示内容
help_text 设置帮助提示信息
error_messages 设置错误信息,以字典格式表示
show_hidden_initial 于检验两次输入值是否一致
Localize 值为True/False,是否支持本地化,如不同时区显示相应的时间.

模型与表单

将表单与模型结合起来形成数据表单。该表单继承于父类forms.ModelForm

1
class ProductModelForm(forms.ModelForm)
1.添加字段

添加模型外的表单字段

1
productId = forms . CharField (max_ length=20,label=' 产品序号')
2.字段转换

通过类Meta实现模型与表单字段的转换。

类Meta的属性说明:

属性 说明
Model 必需属性,用于绑定Model对象
Fields 必需属性,设置模型内哪些字段转换成表单字段
Exclude 与fields相反, 禁止模型内哪些字段转换成表单字段
Labels 可选属性,设置表单字段里的参数label
error_messages 可选属性,设置表单字段里的参数error_messages
3.数据清洗
1
2
3
4
#自定义表单字段weight的数据清洗
def clean_ weight (self):
data = self. cleaned_data['weight']
return data+'g '