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_...

相關文章
相關標籤/搜索