django 获取 axios get 过来的数据_一起DevOps系列12django数据库创建与使用

999f78f177569b87c9088bc8aaa8b960.png

前面的文章,已经分享过数据库的原理,设计与开发的范式,以及根据我们django项目的需求,进行了数据库的设计。另外也介绍过数据库操作的基本SQL命令。

一起DevOps系列10--数据库设计与开发的范式

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

No.1

django数据库ORM

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

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

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

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

python manage.py makemigrations python manage.py migrate

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

No.2

编辑model

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

# -*- coding: utf-8 -*-from __future__ import unicode_literalsfrom django.contrib.auth.models import Userfrom 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)    username = models.ForeignKey(User, to_field='username', on_delete=models.CASCADE)    ssex = models.CharField(max_length=10, 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)    username = models.ForeignKey(User, to_field='username', on_delete=models.CASCADE)    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'。

系统为什么要创建这些表格,怎么定义表格的字段与关联关系,详见之前的文章:

一起DevOps系列10--数据库设计与开发的范式

唯一与之前设计有区别的地方,是student与teacher表里面,原来的susername与tusername修改为了外键引用User表里面的username。

因为django自带用户身份的User类,另外类下面还有身份验证等方法,为了可以直接利用,我们直接把student与teacher表里面的username外键引用该表的username字段。

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

python manage.py makemigrations

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

python manage.py migrate

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

0d9dcf925f877a35a0eb53f555fc4a04.png

No.3

ORM操作数据库

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

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

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

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

#查询所有行列数据instance.objects.all()#只查询user列数据instance.objects.all().values('user') #只查询id和user列,并取出并生成一个列表 instance.objects.all().values_list('id','user')#查询id=1的结果,并且作为一个对象返回整行内容。(注意get如果查询到满足的结果有多个,会报错。get返回的是对象,可以直接print) instance.objects.get(id=1)#查询id=1的结果,filter返回的是一个queryset(查询集),其实就是个SQL命令,但是不会立刻执行查询,只有前端调用之后,才会真正执行查询,所以直接print是print不出来的。filter可以查询支持有多个结果匹配。instance.objects.filter(id=1)

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

连接

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

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

data = teacher.objects.filter(username=username).values('course__cno', 'course__cname','course__score__sno__sname', 'course__score__cscore','course__score__sno__sno')

懂得OCM操作数据库后,我们可以开始动态网页的开发工作了。

No.4

测试

运行命令创建管理员账户

python manage.py createsuperuser
e7bf5fc231db07fae85d5f42b7465192.png

然后登录django管理后台127.0.0.1:8000/admin

e1086e808cc762f345b913d72bc57506.png

增加testuser用户用于测试。

07585b5058ed3573d44a0e0410235050.png f61985c7f1a1624f8776be1a03224d59.png 59026a9e3601eeeefcd5bc2317185f6f.png

然后回到之间的index.html静态文件里面,对于

表单标签,增加method=‘POST’,表示按了表单提交按钮之后,会将内容按照POST的方法发送到后端。
class=        
class="form-group clearfix "> class="col-sm-3 control-label bk-lh30 pt0">用户名:
class="col-sm-9"> "text" class="form-control bk-valign-top" name="username" placeholder="请输入用户名">

class

="help-block">
class="form-group clearfix "> class="col-sm-3 control-label bk-lh30 pt0">密码:
class="col-sm-9"> "password" class="form-control bk-valign-top" name="password" placeholder="请输入密码">
class="form-group clearfix">
class="col-sm-9 col-sm-offset-3"> "submit" class="king-btn mr10 king-success">提交 "button" class="king-btn king-default ">取消

并且需要修改用户名与密码的input,加入name,分别叫username与password,密码的type修改为password,提交按钮的type修改为submit。

在views里面导入models里面的对象。

from stumgr.models import *

在views里面导入django自带的身份认证模块

django.contrib auth

修改原来的index函数,编写业务逻辑。

def index(request):    if request.method == 'POST' and request.POST:        username = request.POST['username']        password = request.POST['password']        userinfo = auth.authenticate(username=username,password=password)        if userinfo:            return HttpResponseRedirect('/stuinfo/')    return render(request,'index.html')

request.method判断form提交的方法是否post,另外request.POST是为了检测是否有POST,如果没有,直接按照原来方式返回index.html

通过request.POST['xxx']可以获取前端页面POST过来的name对应是xxx的标签里面的值。

然后调用django自带的auth.authenticate方法,进行用户名密码校验,如果检测不通过,就会返回None值。判断返回值是否None,如果不是,就将页面重定向到登录后的页面。如果为None(即验证用户名密码不通过),则再次跳转到当前页面。

至此,可以开始测试。

ce18fb50e8d8727499be5fdcf564999e.png

验证通过,跳转登录后的页面。

60da10af8d1137b70c1012dd94faddae.png c37d71b797441a7e5c5aec2179458ed7.png

验证不通过,再次跳转到当前页面。

4480880dd0ac96142cadce05e5ed9051.png

但是当前有个bug,就是如果用户直接访问127.0.0.1:8000/stuinfo/等详细url,是可以直接绕过index页面进入的。

修复这个bug,需要在每个函数前面增加装饰器,@login_required。

编辑view.py,在开头增加导入

from django.contrib.auth.decorators import login_required

然后在每个页面的返回函数前面,增加@login_required。

@login_requireddef stuinfo(request):    return render(request,'stuinfo.html')@login_requireddef selcourse(request):    return render(request,'selcourse.html')@login_requireddef queryscore(request):    return render(request,'queryscore.html')@login_requireddef mopasswd(request):    return render(request,'mopasswd.html')

然后index验证用户名密码后,需要增加auth.login函数进行登录,再带着登录验证信息跳转页面。

另外request.session['username']是将当前用户名保存在会话当中,当前不加这一句不影响业务,但是不加会影响后面的业务逻辑(例如修改密码,需要知道当前登录的是哪个用户),所以现在必须要先加上。

def index(request):    if request.method == 'POST' and request.POST:        username = request.POST['username']        password = request.POST['password']        userinfo = auth.authenticate(username=username,password=password)        if userinfo:            auth.login(request,userinfo)            request.session['username'] = username            return HttpResponseRedirect('/stuinfo/')    return render(request,'index.html')

直接访问127.0.0.1:8000/stuinfo/尝试,会报错。

014c754eda5954deeeddacfea1a64268.png

再次通过127.0.0.1:8000或者127.0.0.1:8000/index/登录跳转,正常进入stuinfo页面。

60da10af8d1137b70c1012dd94faddae.png 425ab09f32b286a5b33ec430826ef917.png

扫码关注我们

公众号 : Waiting的运维日常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值