2018.9.6更新
:尝试了一下REST framework实现先后端分离,新的文章以下Django先后端分离之REST framework初试html
2018.8.27更新
:可另外用 restful API 实现先后端分离,这篇文章可能局限性太大,只是我的的入门实践前端
刚刚学习前端快一年,后台方面了解甚少,因而决定踩踩坑,学习一下。因而就选了django这个框架(刚恰好顺便学了python)
不想使用框架的提供的模板功能,因而看看先后端分离 + MySQL
数据库如何实现
之间也踩了不少坑,从MySQL配置的版本问题,到本地测试的跨域问题
等等
啊,废话少说,看目录python
1、建立项目
2、配置MySQL
3、建立应用
4、结语mysql
过程比较详细记录了先后端分离的每一步,算是小白实践吧哈哈git
到想要建立项目的文件夹下运行命令github
$ django-admin startproject dj_experiment //后面就是项目名字咯
建立完后生成目录,具体什么意思请看官网文档(https://docs.djangoproject.co...)ajax
dj_experiment/ manage.py dj_experiment/ __init__.py settings.py urls.py wsgi.py
这里咱们默认安装好MySQL了,而且为这个小实验建立一个数据库叫作'dj_experiment_db'
Django的配置文件中将SQLite做为默认数据库。同时Django支持sqlite3,MySQL等数据库,在settings.py中修改配置就好,并且由于有丰富的API,因此若是改动数据库,也不须要修改models.py中的代码
如下分为几个步骤:sql
pip install pymysql
python3不支持MySQLdb,因此用pymysql
代替数据库
在settings.py中找到DATABASEdjango
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', #数据库引擎 'NAME': 'dj_experiment_db', #数据库名 'USER': 'root', #帐户名 'PASSWORD': 'password', #密码 'HOST': 'localhost', #主机 'PORT': '3306', #端口 } }
接着在_init_.py添加以下代码
import pymysql pymysql.install_as_MySQLdb()
而后设置TIME_ZONE为本身的时区
TIME_ZONE = 'Asia/Shanghai'
最后执行数据库迁移命令
python manage.py makemigrations python manage.py migrate
而后咱们登陆数据库,链接数据库dj_experiment_db,输入show tables;就能够看到django建立的框架应用的表了
到dj_experiment目录下运行命令,这里咱们建立一个注册的应用,而后在页面里面循环渐进实现作如下先后端分离,开发后台接口的两个小实验:1.ajax与get的后端接口
2.ajax与post提交
两个简单的小实验,但过程当中有些问题:本地测试的跨域问题
,CSRF问题
。
咱们在实践过程当中再逐一解决
如今先建立应用register(先在这个应用实现get,再实现post):
$ python manage.py startapp register
建立完后目录以下:
register/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py
在views.py下建立接口,咱们先举个简单的例子——hello接口
代码以下
from django.shortcuts import render from django.http import JsonResponse def hello(request): return JsonResponse({'result': 200, 'msg': '链接成功'})
而后将一个URL映射给此接口
在register目录中新建一个urls.py文件
,输入如下代码
from django.urls import path from . import views urlpatterns = { path("helloApi", views.hello, name='hello')#第一个参数表示路径 }
接着在dj_experiment/urls.py中指定咱们建立的register.urls模块
from django.contrib import admin from django.urls import path, include urlpatterns = [ path("register/", include("register.urls")), path('admin/', admin.site.urls), ]
最后打开django的开发服务器,测试一下接口
$ python manage.py runserver
浏览器访问:http://localhost:8000/register/helloApi
能够看到以下显示
由于没有进行utf-8编码,因此显示的是Unicode编码
这里推荐用火狐浏览器进行接口测试,看起来更加详细
ok,接口开发完毕了,咱们怎么进行先后端分离呢
在根目录建立一个html文件夹,并在里面建立register.html,,如图
咱们先进行get后台接口的访问
先编写一个ajax的封装函数
ajaxResponse(xhr, 链接成功时执行的函数,链接失败时执行的函数)
便于咱们调用,代码以下
function ajaxResponse(xhr,successFunction,falseFunction) { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { console.log(xhr.status); if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { alert("成功"); successFunction(); } else { alert("失败" + xhr.status); falseFunction(); } } } }
接下来编辑register.html以下:
<div id="getHelloApiDiv" style="background: aqua;height: 100px;width: 100px"></div> <script> let getApiDiv = document.querySelector('#getHelloApiDiv'); let xhr = new XMLHttpRequest(); getApiDiv.onclick = function(){ ajaxResponse( xhr, function () { let helloText = JSON.parse(xhr.responseText); getApiDiv.innerText = helloText.msg; },function () { } ); xhr.open('get','http://localhost:8000/register/helloApi'); //接口写在这里 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.send(null); }; </script>
而后咱们来解决本地测试时的跨域问题
在register/views.py中编写一个返回html的接口,代码以下,注意import了render_to_response方法
from django.shortcuts import render, render_to_response from django.http import JsonResponse # Create your views here. def registerPage(request): return render_to_response("register.html")
接着同理在register/urls.py中加入接口路径,最后是这样子的代码
from django.urls import path from . import views urlpatterns = { path("helloApi", views.hello, name='hello'), path("registerPage", views.registerPage, name='registerPage') }
最后浏览器访问http://localhost:8000/register/registerPage
而且点击方块,接受msg成功 (疑问:放在服务器端的话是否须要这样?)
如今咱们将建立真正的应用,与MySQL进行交互
django经过模型与数据库进行交互
咱们叫这个模型为UserInfo
,字段有username和password,因此代码以下(__str__方法是为了方便命令行显示与管理页面显示)
from django.db import models # Create your models here. class UserInfo(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=20) def __str__(self): return self.username
建立模型后,django能够为应用建立数据库schema和与username,password对象进行交互的python数据库API。如今咱们要作的是激活模型
首先在settings.py的INSTALLED_APPS中添加设置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'register.apps.RegisterConfig',#这里 ]
接着运行命令,检测模型文件的修改,并把修改的部分储存为一次迁移(注意这里尚未修改)
$ python manage.py makemigrations register
而后能够运行命令看看等会的迁移命令会执行哪些SQL语句(这一步可干可不干)
$ python manage.py sqlmigrate register 0001
最后就执行迁移命令
$ python manage.py migrate
显示以下(WARNINGS是对MySQL Strict Mode 的提示):
以后能够在MySQL下看见django建立的表
(这里能够用命令行尝试django提供的api或者配置并打开管理员页面,能够去官网看看怎么作https://docs.djangoproject.co...)
django自带CSRF防御机制,因此咱们这里加个@csrf_exempt屏蔽装饰器
#新的引入文件 from django.views.decorators.csrf import csrf_exempt import json from .models import UserInfo @csrf_exempt #屏蔽装饰器器 def registerApi(request): if request.method == 'POST': req = json.loads(request.body) #取得数据 userID = req['userID'] pwd = req['pwd'] searchArray = UserInfo.objects.get_or_create(username=userID) #尝试建立用户 print(searchArray) if searchArray[1] == True: return JsonResponse({'result': 200, 'msg':'注册成功'}) else: return JsonResponse({'result': 200, 'msg':'已有重复用户名'})
一样urls中记得改配置:
urlpatterns = [ path("helloApi", views.hello, name='hello'), path("registerPage", views.registerPage, name='registerPage'), path("registerApi", views.registerApi, name='registerApi') ]
接着编写html页面
<p>帐号:</p><input type="text" id="userID"> <p>密码:</p><input type="password" id="pwd"> <button id="submit">注册</button>
还有js
let subBt = document.getElementById('submit'); subBt.onclick = function () { let userID = document.getElementById('userID').value; let pwd = document.getElementById('pwd').value; let xhrRegister = new XMLHttpRequest(); ajaxResponse(xhrRegister, function () { let respones = JSON.parse(xhrRegister.responseText); alert(respones.msg); },function () { }); let user = { userID:userID, pwd:pwd }; xhrRegister.open('post', 'http://127.0.0.1:8000/register/registerApi'); xhrRegister.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=utf-8'); xhrRegister.send(JSON.stringify(user)); };
注册成功
还有注册失败
简单的实践目前就到此为止啦,作此次实践的主要目的是了解后台的框架,之中还有不少没有去学习,好比如何在服务器上部署Django,Token验证,数据库操做等等
有什么问题或者哪里不对你们提出来讨论下吧
参考资料:
MySQL驱动:https://blog.csdn.net/liuweiy...
django数据库:https://code.ziqiangxuetang.c...
配置MySQL:https://www.cnblogs.com/wcwni...
屏蔽装饰器:https://blog.csdn.net/lw_zhao...
django加载静态网页:https://blog.csdn.net/github_...