在前面(【实战演练】数据库基本知识与原理系列http://www.javashuo.com/article/p-hbgxkaue-cp.html)的文章,已经分享过数据库的原理,设计与开发的范式,以及根据咱们django项目的需求,进行了数据库的设计。另外也介绍过数据库操做的基本SQL命令。php
之前不使用web框架来进行开发,那么就须要在一个php或者py文件(页面文件里面),从展现层(html、css、js)到逻辑层(php、python)到数据层(SQL)的东西都要写。直接用pymysql用什么pymysql.connect()链接数据库,而后用pymysql.fetchall()在里面写具体sql语句来操做数据库。css
一、django数据库OCMhtml
而这样的最大问题是展现层、逻辑层、数据层没有分离,每一个开发人员都要从前端到后端所有懂,而且代码很难复用,因此引用了MVC模型的开发框架将3者分开。前端
此外,django里面有一套叫OCM的操做命令,来封装了SQL语句,不用具体写SQL命令,这样有什么好处呢?python
不一样版本数据库SQL有微小差别:mysql、oracle、sql server整体上sql的增删改查命令都是同样的,可是细节上仍是有一些小差别的。因此若是须要将系统从mysql数据库迁移到oracle数据库,那么极可能须要对代码进行重写,不然会出BUG。mysql
而django直接使用OCM命令封装SQL,其实OCM就已经自动匹配与翻译SQL命令,在settings.py文件里面,就能够指定django项目使用什么数据库,而后执行
web
python manage.py makemigrations python manage.py migrate
系统就会自动生产对应配置了的数据库(例如oracle)的SQL命令,而且对数据库进行操做。sql
二、编辑models数据库
只须要编辑app里面的models.py文件,就能够建立数据库表了。
django
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class student(models.Model):
sno = models.CharField(max_length=10,unique=True,primary_key=True)
sname = models.CharField(max_length=10,null=True)
ssex = models.CharField(max_length=10,null=True)
susername = models.CharField(max_length=20,null=True)
sage = models.CharField(max_length=10,null=True)
sdept = models.CharField(max_length=10,null=True)
class teacher(models.Model):
tno = models.CharField(max_length=10,unique=True,primary_key=True)
tname = models.CharField(max_length=10, null=True)
tusername = models.CharField(max_length=20,null=True)
ttitle = models.CharField(max_length=10, null=True)
class course(models.Model):
cno = models.CharField(max_length=10, unique=True, primary_key=True)
cname = models.CharField(max_length=10, null=True)
ccredit = models.CharField(max_length=10, null=True)
ctime = models.CharField(max_length=10, null=True)
cplace = models.CharField(max_length=10, null=True)
tno_id = models.ForeignKey(teacher,to_field='tno',on_delete=models.CASCADE)
class score(models.Model):
cno = models.ForeignKey(course, to_field='cno', on_delete=models.CASCADE)
sno = models.ForeignKey(student, to_field='sno', on_delete=models.CASCADE)
cscore = models.IntegerField(null=True)
每一个字段能够按照须要自定义类型,具体能够查阅官方文档,其中CharField是字符串,DateFiled是时间戳,IntergeFiled是整数,foreignkey就是外键,CASCADE是级联删除,即若是主键删除了,要级联删除。部分django版本写成on_delete='CASCADE'
系统为何要建立这些表格,怎么定义表格的字段与关联关系,详见以前的文章:(【实战演练】数据库基本知识与原理系列02-数据库设计与开发的范式http://www.javashuo.com/article/p-hbgxkaue-cp.html)
而后执行makemigrations,是将models里面的数据库表建立的需求,转为对应mysql配置的SQL命令。
python manage.py makemigrations
而后对配置好的数据库进行转换后的命令操做。
python manage.py migrate
执行完毕后,直接用navicat for mysql去数据库查看,数据库表已经成功建立了。
三、OCM操做数据库
django使用OCM对数据库进行操做,固然也是增、删、查、改、链接5大类操做。
instance按照实际修改,例如编辑student表,那么instance就是models.student代替。
3.一、增
instance.objects.save() instance.objects.create(username='张三',pwd='123456')
3.二、删
instance.objects.filter(username='张三').delete()
3.三、查
instance.objects.all() instance.objects.all().values('user') #只取user列 instance.objects.all().values_list('id','user') #取出id和user列,并生成一个列表 instance.objects.get(id=1) #get返回的是对象 instance.objects.filter(id=1) #filter是返回一个id=1的一整行,返回的值是一个序列。
3.四、改
instance.objects.filter(username='zhangsan').update(pwd='123456')
3.五、链接
OCM的链接会比SQL更加方便,只要创建数据库表的时候作好了foreign外键的链接,就会自动作好关联,只须要输入当前查询的表格所直接关联的表名双下划线字段名就能够了。例如当前查询的是teacher表,那么与之直接关联的是course表,因此能够filter对teacher表字段进行筛选,而后要返回的values,course的字段能够直接用course__sno来表示,而course表与score表作了关联,因此若是要显示score表的字段,须要用course__score_sno来表示。
data = teacher.objects.filter(tusername=username).values('course__cno', 'course__cname',
'course__score__sno__sname', 'course__score__cscore',
'course__score__sno__sno')
懂得OCM操做数据库后,咱们能够开始动态网页的开发工做了。
四、OCM操做数据库
为了方便测试与掌握OCM操做数据库技巧,咱们如今models.py里面增长一张用户名密码表,用户登陆页面的操做。(后期不用这张表)
testuser(models.Model): username = models.CharField(=) password = models.CharField(=)
python manage.py makemigrations python manage.py migrate
用navicat for mysql手工在testuser表里面建立一个测试用户。
而后回到之间的index.html静态文件里面,对于<form>表单标签,增长method=‘POST’,表示按了表单提交按钮以后,会将<form>内容按照POST的方法发送到后端。
而且须要修改用户名与密码的input,加入name与id,分别叫username与password
<form class="form-horizontal" method="post"> <input type="text" class="form-control bk-valign-top" name="username" id="username" placeholder="请输入用户名"> </div> <input type="text" class="form-control bk-valign-top" name="password" id="password" placeholder="请输入密码"> </div>
而且submit的按钮的type改成submit。
<button type="submit" class="king-btn mr10 king-success">提交</button>
在views里面导入models里面的对象。
models *
修改原来的index函数,编写业务逻辑。
经过request.POST.get()能够获取前端页面POST过来的变量的值。
经过testuser.objects.get(username=username)能够查询数据库,前面的username是testuser的字段名,后面的username是request.POST.get获取值回来后赋值到username的这个变量。
若是查询到有数据,赋值给userinfo,userinfo.password表示密码的这个数据,用if作对比后,为真,则返回登录后的页面,不然仍是跳转到当前页面。
(request): request.method == request.POST: username = request.POST.get() password = request.POST.get() userinfo = testuser.objects.get(=username) userinfo.password == password: render_to_response(()) render_to_response(())
至此,能够输入用户名密码进行测试了。
输入正面的用户名密码,点击提交,用户名密码正确后,就会自动跳转。
输入错误的用户名/密码,点击提交后,又回到了当前页面。