上期的课程当中,已经学习了Django基本的请求,基于MVC来说,学习了V和C部分,紧接着要学习的就是Django的模型部分。首先要搞明白的是数据建模。
所谓的数据建模就是利用数据库语句来描述我们的业务逻辑。描述将会被分为两个部分:
业务实体的描述
业务关系的描述
举个例子:
我们现在要对班级的同学和老师进行数据建模
首先,我们会考虑的是老师和同学这两个主体,所以,我们会搭建出以下的表:
Teacher表:需要的数据:Name、Age、Project(学科)
Student表:需要的数据:Name、Age、Project、Score、Photo、Email
Name、age、project和score在工作中我们把它称为字段,字段就是表头。
这两张表虽然将所有内容都包含进去了,但是没有强调到老师和学生的关系,那么接下来就需要一个表来关联学生和老师,因为这是一个多对多的关系,所以中间表是必不可少的。来关联学生,效果如下:
业务实体的描述:
Teacher表:需要的数据:Name、Age、Project(学科)
Student表:需要的数据:Name、Age、Project、Score 、Photo、Email
业务关系的描述:
S_T表:需要数据T_id,S_id,Tag(用来判断是否老师和学生匹配)
所以我们最后得到的就是这样的一个效果了,我们通过S_T表可以描述简单的师生情况与关系,在这里必须强调,好的建模是成功的一半。
接着来了解一下Python数据库部分的一个高级的知识点
一、ORM
ORM被称为数据库映射关系。
之前我们学数据库时使用过pymysql(日记mysql(五)最后),也是用python来存取数据库数据, Python可以通过pymysql模块访问到mysql数据库,并且获取数据,大概思路如下:
这样可以很直观的看到数据库存取数据的效果,但从另外的一个角度来看也是有问题的。比如:
开发必须要懂MySQL,因为我们增删改查数据的时候使用的是sql语句。
如果要切换数据库就必须修改所有的数据库语句
所以,就有了Python ORM数据库映射的需求,然后有了功能
也就是说,在操作数据库的时候,开发人员不直接接触数据库语句,而是选择用Python描述数据库,然后将描述传递给ORM,ORM将描述翻译为sql语句传递给MySQL进行执行。这样一来上面的问题迎刃而解。而Django就是采用ORM映射来处理数据库。
二、Django模型处理
Django本身是鼓励开发者进行相对独立的项目开发的,所以,Django的设计理念当中有一个关键的元素,叫做app,所谓的app就是项目当中具体的功能。这个并不是手机软件那个app。
django充许在一个项目中存在多个app,如一个大门户网站中可以包含论坛,新闻等内容,其中每一个模块称之为一个app,也可以理解为一个个独立的小型项目(app)最终集成在一个门户网站中最终呈现给用户
比如:我们开发一个商场的项目
可以将整个网站划分为:商品、用户(买家与卖家)、店铺
三个独立的功能进行开发,这样可以让我们的思路更加清晰,同时,也方便我们的功能块儿的迁移。那么接下来开始学习Django 模型部分的知识,Django模型的使用通常按照以下的思路学习。
1、创建项目
进入虚拟环境,创建项目,项目名为school
2、创建app
切入项目目录
执行app创建命令
命令: python manage.py startapp Persion
然后完成了项目的基本创建
用pycharm打开项目,配置环境,添加static和template目录,在setting中修改添加static和template目录关联。既然我们创建了app,如何把app与项目关联呢?还是通过修改配置文件,在配置文件中把app添加进项目
三、数据建模
我们刚才已经想好了如何去建立老师、学生的表,那接下来就要通过django来将这三个表写入数据库。
在app(persion)中找到文件models.py这就是我们mvc中的m。
在models文件中开始编写三个表,表以类的形式呈现,并需要继承django提供的模型,这样你建立的模型才会被认作为模型,要不就是一个普通的类。
类中内容为字段和字段类型,字段就是表头,也就是name、age、project等等,英文field的意思就是字段。我们需要限制字段的类型例如姓名为字符串字段(CharField),邮箱为邮件字段(EmailField)、照片为照片字段(ImageField)等等。字符串(CharField)字段必须写上最大长度max_length。Django的模板默认会为所有表添加id。
1、常用字段属性
IntegerField(Field) 整数
CharField(Field) 字符串
EmailField(CharField) 邮件
IPAddressField(Field) ipv4协议
FileField(Field) 文件
ImageField(FileField) 图片
DateTimeField(DateField) 时间 年月日 时分秒
DateField(DateTimeCheckMixin, Field) 年月日
TimeField(DateTimeCheckMixin, Field) 时分秒
2、照片字段(ImageField)
照片上传功能是需要安装一个模块pillow,进入虚拟环境然后使用命令安装,当然你也在真实环境里安一个,以供不时之需:
Pip install pillow(项目使用一定要在虚拟环境下,要不项目使用不到)
照片字段带有一个属性为:upload_to=路径,路径必须使用相对路径!代表照片上传后存在哪里。数据库中的照片通常是学生自己上传的照片,学生上传的照片应该存放于静态文件夹下的照片文件夹中,所以upload_to = static/img/
3、编写models文件
今天以学生为主,所以我将学生的字段进行了扩展,老师和中间表暂时用不上。
通过models文件我们就可以给数据库传输这些信息填充我们的学生表,那如何将表写入数据库呢?
4、配置数据库
默认Django采用sqllite3数据库、我们使用mysql,修改配置在setting文件中
修改前setting文件中关于数据库的设置
修改这个设置,添加数据库名称、用户名、密码、端口(数据库默认3306)、主机、和使用何种数据库,修改后为这样:
5、同步数据库
上面我们已经在项目中建立好了库中表的结构,也配置好了数据库信息,那如何把表放入库中?
首先我们在MySQL中建立一个名字为schoolLib的数据库,这个要保持与你在配置文件设置的数据库名称一致,你可以通过pycharm绑定数据库,直接图形化操作,也可以使用cmd。
[1]建立schoolLib数据库
建立数据库的时候一定要注意编码格式,保险起见我们建立时添加编码格式
Create database schoolLib charset=utf8;
[2]校验models文件是否有误
一定要进入虚拟环境并进入项目文件,因为你的项目是在虚拟环境中建立的,而且你校验的时项目的models文件。
Python manage.py check
我这里报了错,是因为在setting文件设置静态文件目录时,我忘记加逗号了,着重提醒个位
还有一个报错要注意,如果提示你did you install mysqlclient什么的,是因为python3采用的是pyMySQL(py3)数据库api,但是Django默认的是MySQLdb(py2)模块,所以需要做以下修改
校对成功显示no issues
[3]生成数据库
Python manage.py makemigrations
[4] 进行数据库同步
Python manage.py migrate
数据库就构建完成了,我们可以查看数据库中的表:
查看表头:
这样我们数据库就建好了,表也有了,接下来就是数据传入。
这里要说一下删库操作,我们在做数据的过程中可能会发现各种问题,有时候数据库数据不足或者其他的问题,如果修改数据库并不能解决问题,就只能删库了,删库要先删除schollib库,还有删除app中的数据库记录文件
四、Django自带模块 admin
今天我们先不学习如何通过注册页面来获取用户数据,转而把数据保存到数据库。
今天来看一个django给我们提供的写好的数据管理页面admin
每次你配置路由(urls)的时候,难道就不好奇
这个admin页面是个啥,运行项目,进去看看
Django 2版本之前默认创建后台超级用户,2.0之后,我们需要借助命令自己创建用户来访问后台。
进入虚拟环境,进入项目、然后输入:
Python manage.py createsuperuser
如果想让admin显示自己的数据库,还需要关联数据库:
我们还可以修改admin界面的语言,在setting文件中进行设置:zh-hans代表中文
这时候我们再次访问admin页面输入密码,进入:
可以看到我们创建的表:
进入表,可以添加数据:
点击添加,你会发现里面要输入的都是我们之前在model中创建的字段。
添加几个数据,
这里1-奥巴马就是我们当时写在model中所用的魔术方法。
然后查看我们数据库
这样就实现把数据写进了数据库。
五、小总结
我们把数据存入数据库做一个小总结
1、创建app
2、创建models:创建模型
Class 表名(models.Model)
字段名=models.字段类型
Def __str__(self)
Return
3、配置
INSTALL_APP:关联app
TEMPATES:关联html
DATABASES:关联数据库
STATICFILES_DIRS:关联静态文件
4、同步
Python manage.py check
Python manage.py makemigrations
Python manage.py magrate
5、admin页面
Python manage.py createsuperuser
在admin文件中:
From app.models import 表
Admin.site.register(表)
六、从数据库中提取数据
我们在工作中,很多时候网页斌不需要自己一句一句去写,而是使用一些模板就能完成相应的需求,今天通过使用一个后天管理系统的列表页来学习获取数据。
1、导入页面
提供一个非常有名的后台管理系统模板(https://codeload.github.com/BlackrockDigital/startbootstrap-sb-admin/zip/gh-pages)
下载下来,我们将文件中html复制到我们项目的template文件夹中(可以只复制table. Html页面,今天只用这个),把css,js,scss,vendor文件复制到static文件夹下。
打开table页面,由于我们改变了模板原先的静态文件位置,所以我们需要在页面中修改导入js、css的路径
推荐使用crtl+r进行替换,但是也要注意不要把句子中的文本替换了,我们给路径加上/static/,别忘了还有下面的js文件路径。
2、修改视图和路由
既然要打开页面,那我们就得在路由和视图中进行关联,修改内容如下:
接下来就可以访问该页了,而我们接下来要做的内容就是如何把我们存在student中的数据放在这个页面的表格中展示出来
3、从数据库获取数据
数据是存在视图中的,所以我们在试图中获取数据
获取数据有三种方法
首先方法object是django提供的从数据库取数据的方法
[1]表.object.all()
获取所有表中数据,以列表中套字典的方式取出
[2]表.object.get()
获取想要得到的数据,例如get(id=1)、get(name=张三),但是如果数据库中不存咋该数据,就会报错,获取的数据格式为字典,里面是符合条件这个数据的所有字段信息
[3]表.object.fillter()
获取想要得到的数据,例如fillter(id=1)、fillter(name=张三),返回的数据为一个列表,列表中存着匹配到的成员的字典,如果没匹配到列表为空,但是不会报错。获取到需要取出其中字典再进行使用。
我们使用all来获取所有student表中的数据
4、将数据写入页面
先把模板中自带的这些表中数据删除,留下表头进行修改,我们在学员列表页面只展示几个项目即可,例如id、姓名、年龄、等等、详细的内容可以放在学员详情页进行展示例如照片
详情页稍后再说,先把列表页做好。
[1]修改表头
[2]通过for循环标签获取数据,我们在view中把studentList传入了该页
查看页面:
5、制作学员详情页面
学生总共有11项数据,我们在列表页展示了6项,我希望通过点击学生姓名来查看更多数据应该如何呢?
我们还是使用这个页面的格式,只不过把其中表格部分删除,改为展示页,命名为studentInfo.html
在路由(urls)和视图(view)界面做关联,因为学生列表页面也要获取学生表数据,所以也要写上获取数据的语句。
这时候问题就来了
[1]我们如果有100个学员,不可能建立100个studentlist页面来显示详细信息
[2]获取数据我们要获取的为当前详情页的学生数据
让我们想想有什么字段是每个学生独一无二不会重复的,当然是id,
我们可以使用studentlist/id的方式显示页面,id是一个可变数,但是都是数字,我们可以用正则进行匹配,这样1个页面就可以完成所有人的详情,那详情页的内容呢?
所以我们获取数据通过id来获取,那id如何传入视图(view)的函数中,当然是给试图函数传递参数。Urls中path(‘studentList/id’,studentList),会把前面的网址(studentList/id)作为参数传入后面的函数(studentList)。
那最后一个问题,如何保证传入的数据(id)就是我点击的那个人的id,当然是通过列表页我们点击姓名的时候的a标签确定了。
所以,第一步,先给学生详情页绑定视图和路由,在视图的函数中我们多添加一个参数num。
正则那里使用([0-9])也可以,一定要加括号,才会认为是参数。
第二步:给学生列表页,学生姓名处添加a标签
传入id,在路由中通过正则进行匹配,然后把id传入列表页的函数,列表页获取该id信息,送到列表页。
第三步、写列表页
然后就可以通过点击列表页学员姓名访问详情页