在前面(【实战演练】数据库基本知识与原理系列https://blog.51cto.com/14423403/2418820)的文章,已经分享过数据库的原理,设计与开发的范式,以及根据我们django项目的需求,进行了数据库的设计。另外也介绍过数据库操作的基本SQL命令。


以前不使用web框架来进行开发,那么就需要在一个php或者py文件(页面文件里面),从展示层(html、css、js)到逻辑层(php、python)到数据层(SQL)的东西都要写。直接用pymysql用什么pymysql.connect()连接数据库,然后用pymysql.fetchall()在里面写具体sql语句来操作数据库。


1、django数据库OCM

而这样的最大问题是展示层、逻辑层、数据层没有分离,每个开发人员都要从前端到后端全部懂,并且代码很难复用,所以引用了MVC模型的开发框架将3者分开。

此外,django里面有一套叫OCM的操作命令,来封装了SQL语句,不用具体写SQL命令,这样有什么好处呢?

不同版本数据库SQL有微小差异:mysql、oracle、sql server总体上sql的增删改查命令都是一样的,但是细节上还是有一些小差异的。所以如果需要将系统从mysql数据库迁移到oracle数据库,那么很可能需要对代码进行重写,否则会出BUG。

而django直接使用OCM命令封装SQL,其实OCM就已经自动匹配与翻译SQL命令,在settings.py文件里面,就可以指定django项目使用什么数据库,然后执行

python manage.py makemigrations
python manage.py migrate

系统就会自动生产对应配置了的数据库(例如oracle)的SQL命令,并且对数据库进行操作。


2、编辑models

只需要编辑app里面的models.py文件,就可以创建数据库表了。

# -*- 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-数据库设计与开发的范式https://blog.51cto.com/14423403/2418820)

然后执行makemigrations,是将models里面的数据库表创建的需求,转为对应mysql配置的SQL命令。

python manage.py makemigrations

然后对配置好的数据库进行转换后的命令操作。

python manage.py migrate

执行完毕后,直接用navicat for mysql去数据库查看,数据库表已经成功创建了。

3、OCM操作数据库

django使用OCM对数据库进行操作,当然也是增、删、查、改、连接5大类操作。

instance按照实际修改,例如编辑student表,那么instance就是models.student代替。

3.1、增

instance.objects.save()
instance.objects.create(username='张三',pwd='123456')

3.2、删

instance.objects.filter(username='张三').delete()

3.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.4、改

instance.objects.filter(username='zhangsan').update(pwd='123456')

3.5、连接

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操作数据库后,我们可以开始动态网页的开发工作了。


4、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静态文件里面,对于

表单标签,增加method=‘POST’,表示按了表单提交按钮之后,会将内容按照POST的方法发送到后端。

并且需要修改用户名与密码的input,加入name与id,分别叫username与password