Django先后端分离实践

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

1、建立项目

到想要建立项目的文件夹下运行命令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

2、配置MySQL

这里咱们默认安装好MySQL了,而且为这个小实验建立一个数据库叫作'dj_experiment_db'
Django的配置文件中将SQLite做为默认数据库。同时Django支持sqlite3,MySQL等数据库,在settings.py中修改配置就好,并且由于有丰富的API,因此若是改动数据库,也不须要修改models.py中的代码
如下分为几个步骤:sql

1.安装pymysql数据库驱动:

pip install pymysql

python3不支持MySQLdb,因此用pymysql代替数据库

2.配置Django中的DATABASE

在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建立的框架应用的表了
clipboard.png

3、建立应用,编写views

到dj_experiment目录下运行命令,这里咱们建立一个注册的应用,而后在页面里面循环渐进实现作如下先后端分离,开发后台接口的两个小实验:
1.ajax与get的后端接口
2.ajax与post提交
两个简单的小实验,但过程当中有些问题:本地测试的跨域问题CSRF问题
咱们在实践过程当中再逐一解决

1.ajax与get的后台接口

如今先建立应用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
能够看到以下显示
clipboard.png
由于没有进行utf-8编码,因此显示的是Unicode编码
这里推荐用火狐浏览器进行接口测试,看起来更加详细
clipboard.png
ok,接口开发完毕了,咱们怎么进行先后端分离呢
在根目录建立一个html文件夹,并在里面建立register.html,,如图
clipboard.png
咱们先进行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成功 (疑问:放在服务器端的话是否须要这样?)
clipboard.png

2.ajax与post的后台接口—注册用户

如今咱们将建立真正的应用,与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

clipboard.png
最后就执行迁移命令

$ python manage.py migrate

显示以下(WARNINGS是对MySQL Strict Mode 的提示):
clipboard.png

以后能够在MySQL下看见django建立的表
clipboard.png

(这里能够用命令行尝试django提供的api或者配置并打开管理员页面,能够去官网看看怎么作https://docs.djangoproject.co...

第三步编写view注册视图:

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));
};

注册成功
clipboard.png

还有注册失败
clipboard.png

4、结语

简单的实践目前就到此为止啦,作此次实践的主要目的是了解后台的框架,之中还有不少没有去学习,好比如何在服务器上部署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_...

相关文章
相关标签/搜索