Django Rest 與 React(Django2.1 + coverage測試 + xadmin + 在線api文檔)-翻譯實踐強化版

原文: www.valentinog.com/blog/tutori…html

翻譯版實踐教程: Django Rest 與 React(Django2.1 加 一點小測試 加一點譯者的小額外功能)前端

最終構建了一個有後臺管理 + 提供api服務 + Mysql數據庫 + 在線api文檔的Lead系統。python

一個實用(自認爲)的介紹: 實用Django REST 與 React,特性! Django2.1!mysql

mark

現在(可供開發選擇的)web框並不匱乏。react

想要構建一個API服務? 這裏列舉出一些你能夠立馬想到說出名字的: Laravel, Rails, Node.js and Koa 2, Phoenix。webpack

可是擺在咱們面前的現實是: 客戶想要一個儘量快的原型,這時我該如何作?git

我選擇了一個web 框架,他:github

  • 讓我能夠寫更少的代碼
  • 讓我能夠儘量遵循MVP模式
  • 爲擴展項目提供了一個穩定的基礎

請信我! 當涉及到開發速度時,Django是很好的一個選擇。 可是如何去建立一個簡單的Django Rest API呢?如何去 組織構建 一個Django 項目 與 React呢?web

不要懼怕,咱們將在下面的教程中一塊兒探索。sql

目錄

  • Django REST with React: 咱們將會學到什麼
  • Django REST with React: requirements(環境依賴)
  • Django REST with React: 爲項目建立一個虛擬的 Python 環境
  • Django REST with React: 構建一個 Django 的 application
  • Django REST with React: 建立一個 Django Model(譯者增 GitHub 託管代碼)
  • Django REST with React: 一丟丟測試
  • Django REST with React: Django Rest serializers(序列化器)
  • Django REST with React: 設置視圖控制器
  • Django REST with React: 設置urls 路由
  • Django REST with React: (seeding)餵養數據庫
  • Django REST with React: Django 與 React 協同
  • Django REST with React: 構建 React 與 webpack
  • Django REST with React: React 前端
  • Django REST with React: 前端測試
  • Django REST with React: 構建一個React 表單
  • Django REST with React: 總結
  • Django REST with React: 資源

Django REST with React: 咱們將會學到什麼

在下面的教程中你將會學到:

  • 如何構建一個簡單的 Django REST API
  • 如何組織構建一個 Django project 與 React

咱們將要作個啥嘞? 在這個項目裏,咱們將會構建一個簡單的 API 來列出並存儲領導。

Django REST with React: requirements(環境依賴)

爲了能繼續跟進下面的教程,你應該擁有:

  • 掌握 Python 與 Django 基礎
  • 掌握 JavaScript ES6 和 React 基礎
  • 在你的電腦系統中安裝一個新版本的 Node.js

準備好了?讓咱們一塊兒出發吧!

Django REST with React: 爲項目建立一個虛擬的Python環境

首要的是來確認你擁有一個虛擬的Python環境,你能夠在Python3中使用 pipenv,pyenv,或者venv模塊。 (譯者推薦使用pipenv)

pip install pipenv
mkdir django-drf-react-quickstart && cd django-drf-react-quickstart
pipenv shell
複製代碼

而後安裝依賴: 安裝Django 和 Django REST framework 經過下面命令:

pipenv install django djangorestframework
複製代碼

當安裝結束,你能夠經過下面命令建立一個新的Django 項目:

django-admin startproject drf_react .
複製代碼

如今咱們能夠開始構建咱們的第一個Django app 來 列出與存儲leads

Django REST with React: 構建一個Django的application

一個Django項目包含許多的 applications(應用)。理想狀態下 每一個應用應該只作一件事。

Django applications(應用) 是模塊化的,可重用的。 例如: 我建立了一個lead 應用用來建立和列出領導。

若是其餘項目須要一個相同的app,我能夠經過 package manager(INSTALLED_APPS) 來安裝leads。嗯,沒錯,這就是所有。

我建議去閱讀 How to write reusable apps,並觀看 DjangoCon 2008: Reusable Apps 來學習關於app的最佳實踐。

在Django中建立一個新的application,你應該運行:

django-admin startapp app_name 
複製代碼

爲了在項目的文件夾中建立leads app:

cd django-drf-react-quickstart
複製代碼

而後初始化咱們的app:

django-admin startapp leads
複製代碼

注意: 我須要假設你位於 /YOUR_CODE_DIR/django-drf-react-quickstart/來運行的上述命令! 以及這些命令是在pipenv shell啓動的虛擬環境下執行的。

mark

你將看到一個新的名字爲leads的文件夾,在你的/YOUR_CODE_DIR/django-drf-react-quickstart/目錄中。

mark

就像上圖這樣。

如今讓咱們告訴Django如何使用這個新的app

打開 ./drf_react/settings.py 並添加這個app在 INSTALLED_APPS中:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'leads', # 添加leads app
]
複製代碼

到目前爲止一切順利。

譯者附加教程(GitHub管理代碼)

  • GitHub 新建Repo

mark

  • GitHub 奪命N連環
# 起手式
git init
# 添加當前文件進入式
git add .
# commit文件式
git commit -m "初始化項目目錄,添加leads app"
# 設置要上哪一個雲端式
git remote add origin https://github.com/mtianyan/django-drf-react-quickstart.git
# 把網頁新建拉下來式
git pull --rebase origin master
# push真的上雲式
git push --set-upstream origin master
複製代碼

首次使用才如上面N連環般麻煩。

  • GitHub 奪命三全
# 第一全,文件全添加
git add .
# 第二全,commit信息要全
git commit -m "巴啦啦小魔仙balala"
# 第三全,全網速推上雲
git push 
複製代碼

Django REST with React: 建立一個Django Model

注意: 在進行下一步以前,請確保你仍然位於: /YOUR_CODE_DIR/django-drf-react-quickstart/

隨着app的安裝,咱們是時候來建立咱們的第一個model了,一個model 是一個對象用來表示你的表數據。幾乎每一個web 框架都擁有models這個概念。 Django 也不例外。

一個Django模型能夠擁有一個或多個字段: 每一個字段是你數據表中的一列,當進行下一步以前,讓咱們爲咱們的lead app 定義它的依賴。

首先咱們須要一個 Lead model

因爲我收集了leads的信息,我認爲一個Lead model 應該擁有如下字段:

  • 一個名字
  • 一個郵件
  • 一個信息

(感受添加額外的字段也很輕鬆,例如咱們想再加個手機號)

請不要忘記一個 時間戳 字段! Django 不會默認的爲你添加一個 created_at 列。

很好!

打開 ./leads/models.py而後建立Lead model:

from django.db import models
class Lead(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()
    message = models.CharField(max_length=300)
    created_at = models.DateTimeField(auto_now_add=True)
複製代碼

這裏有一個關於models的快速指南: 花時間看看 -> Django fields documentation

當計劃一個model時,請盡力選擇對於你的案例最適合的那些字段。

(譯者)附加使用mysql及本地化時間等

pipenv install mysqlclient
複製代碼

新建一個mysql數據庫

mark

settings -> 修改成使用mysql數據庫:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'drf_react',
        'USER': 'root',
        'PASSWORD': '密碼',
        'HOST':'127.0.0.1'

    }
}
複製代碼

settings -> 設置本地化

# 語言改成中文
LANGUAGE_CODE = 'zh-hans'

# 時區改成上海
TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

# 數據庫存儲使用時間,True時間會被存爲UTC的時間
USE_TZ = False
複製代碼

在model定義就位以後,讓咱們一塊兒建立一個migration(遷移) 經過運行:

python manage.py makemigrations leads
複製代碼

並最終 migrate 到數據庫使用下面命令:

python manage.py migrate
複製代碼

能夠看到mysql中生成的表:

mark

很是棒, 下一小節咱們將討論序列化器和試圖,可是首先咱們須要一點小小的測試。

Django REST with React: 一丟丟測試

此時此刻,你或許在驚歎"Valentino(做者名), 咋測試這個app"

不會讓TDD(測試驅動開發) 教程來把你搞崩潰,我將給你一些小技巧(tips)

我見過大量的Django 教程裏都是這樣開始寫的:

class SomeModelModelTest(TestCase):
    def setUp(self):
        SomeModel.objects.create(
            name=fake.name(),
            email=fake.email(),
            phone=fake.phone_number(),
            message=fake.text(),
            source=fake.url()
        )
    def test_save_model(self):
        saved_models = SomeModel.objects.count()
        self.assertEqual(saved_models, 2)
複製代碼

不要這樣作,這對於測試Django model 或 Django ORM 都是沒踩對點的(沒啥用的)。

對於Django裏的測試,這裏有一個好的出發點:

  • 不要測試 Django 的內建代碼(models views 等)
  • 不要測試 Python 的內建函數

總的來講: 不要測試那些已經被測試過的!

那我該測些啥呢? 你是否在Django的model中添加了一個 custom method(自定義的方法)? 測它!

你是否有一個custom view(自定義的視圖)呢? 測它! 可是我怎麼知道要去測試啥呢?

經過安裝工具 coverage 來幫本身一點忙

pipenv install coverage
複製代碼

而後,每當你添加一些代碼到你的應用時,運行coverage:

coverage run --source='.' manage.py test
複製代碼

而後會產生報告:

coverage html
複製代碼

用瀏覽器打開 /YOUR_CODE_DIR/django-drf-react-quickstart/htmlcov/index.html,你將看到你須要測試啥。

若是你更想在命令行裏看到測試報告,你能夠運行:

coverage report
複製代碼

等會! 你堅持看到了這? 我感動死了。

不要停! 牢牢抱住個人大腿, 下一節咱們將看看序列化器(serializers)!

breakpoint: 奪命三全 -> push

Django REST with React: Django Rest serializers(序列化器)

注意: 開始下面以前,請確保你仍然在/YOUR_CODE_DIR/django-drf-react-quickstart/ 目錄。

什麼是序列化? 什麼是Django REST 序列器

序列化是轉換一個對象到另外一種數據格式的一種動做。在對象轉換完成後,咱們能夠將它保存到文件,或者在互聯網中發送它。

爲何序列化如此必要呢?

思考一個Django model: 它是一個Python的嘞, 你該如何在瀏覽器中渲染一個Python的類到JSON 呢?

使用Django REST 序列器!

一個序列器 也能夠反向工做: 它轉換 JSON 到 對象

這種方式你能夠:

  • 經過轉換Django的models到JSON,來在瀏覽器中查看它們。
  • 製做 一個JSON 負載的 CURD(增刪改查) 的請求到API

簡要歸納: DjangoREST 序列器 是操做模型到API的主宰。

建立一個新文件: ./leads/serializers.py. 這個LeadSerializer 接收咱們的Lead model 與一些字段

from rest_framework import serializers
from leads.models import Lead
class LeadSerializer(serializers.ModelSerializer):
    class Meta:
        model = Lead
        fields = ('id', 'name', 'email', 'message')
複製代碼

就像上面你能看到的代碼裏那樣,咱們繼承了ModelSerializer。

一個 ModelSerializer 在Django REST中就像一個 ModelForm

它很是適合於,任何你想接近 映射一個Model 到 一個Serializer 中時。

除了明確的定義須要映射的字段,你也能夠映射model中的全部字段。

from rest_framework import serializers
from leads.models import Lead
class LeadSerializer(serializers.ModelSerializer):
    class Meta:
        model = Lead
        fields = '__all__'
複製代碼

保存並關閉文件,咱們離完成app更近了一步。

下面的章節裏,咱們將看一下 views(視圖) 和 urls。

Django REST with React: 設置視圖控制器

注意: 開始下面以前,請確保你仍然在/YOUR_CODE_DIR/django-drf-react-quickstart/ 目錄。

若是你從其餘框架轉到Django,你可能感到驚奇的是: Django 沒有控制器!

控制器用來封裝處理 request 請求的邏輯並返回response。傳統的MVC 體系 包含 Model(模型), View(視圖), Controller(控制器)

這樣的MVC框架有: Rails, Phoenix, Laravel。

Django 是一個 MVT framework,它有的三層是: Model(模型) - View (視圖) - Template(模板)。其中View(視圖) 關注着請求和響應的一整個生命週期。

Django中不少類型的views: function views 函數視圖, class based views 基於類的視圖, and generic views 通用視圖.

雖然不少開發者相對於class based views(基於類的視圖)更喜歡 function views (函數視圖),但我是後者(基於類)的一個大粉絲

當我選擇Django,由於個人核心價值要求是: 開發速度,DRY(dont repeat yourself),更少的代碼。

當已經存在一組合理的默認值時,我認爲繼續手寫Code是沒有意義的。

這是個人經驗法則:

僅當咱們想要自定義通用視圖所花費的時間超過手動編寫視圖所花費的時間時,才使用函數視圖。

與簡單的Django同樣,在Django REST 框架中,有不少方法能夠編寫視圖:

  • function based views(基於函數的視圖)
  • class based views(基於類的視圖)
  • generic API views(通用的API 視圖)

在這個教程的範圍內,我將使用 generic API view,目的是爲了寫更少的代碼。

咱們的簡單app應該有:

  • 列出模型中的集合
  • 建立一個新的對象到數據庫中

經過閱讀generic API views documentation 咱們能夠看到一件提供給咱們一個能夠用於列出和建立models的view。

它就是 ListCreateAPIView

ListCreateAPIView 接收一個queryset 和 一個序列化類做爲參數。

打開 ./leads/views.py 建立視圖:

from leads.models import Lead
from leads.serializers import LeadSerializer
from rest_framework import generics
class LeadListCreate(generics.ListCreateAPIView):
    queryset = Lead.objects.all()
    serializer_class = LeadSerializer
複製代碼

經過三行代碼咱們建立了一個能夠處理GET 和 POST請求的view。

如今還缺點啥呢? URL 映射! 換句話說,咱們須要映射URLs 到 視圖

咋整? 敬請期待下一節

Django REST with React: 設置urls 路由

注意: 開始下面以前,請確保你仍然在/YOUR_CODE_DIR/django-drf-react-quickstart/ 目錄。

來自Rails, Phoenix, or Laravel 的朋友們,你可能又感到驚訝了,Django居然沒有路由配置。

雖然DRF 提出了 resourceful router 資源化的路由,但最簡單的映射URl到視圖的方式仍是URL mapping

咱們的目標是聯通 LeadListCreate 到 api/lead/

換句話講,咱們想要製做一個GET 和 POST請求到api/lead/ 來 列出和建立models。

./drf_react/urls.py配置URL mapping 包含app(leads)中的urls

from django.urls import path, include
urlpatterns = [
    path('', include('leads.urls')),
]
複製代碼

下一步是建立一個新的文件: ./leads/urls.py:

from django.urls import path
from . import views
urlpatterns = [
    path('api/lead/', views.LeadListCreate.as_view() ),
]
複製代碼

最後: 咱們要讓 rest_framework 註冊進 INSTALLED_APPS。

打開 ./drf_react/settings.py 而後添加app 進入INSTALLED_APPS。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'leads', 
    'rest_framework' # 加入 rest framework
]
複製代碼

此時你應該能夠經過健全性檢查:

python manage.py runserver
複製代碼

訪問: http://127.0.0.1:8000/api/lead/ 你將會看到 browsable API 可瀏覽式api

mark

此時你能夠經過網頁上內建的表單來建立一些數據

在下一節中,咱們將學習如何在Django 中餵養數據庫(-v-)

Django REST with React: (seeding)餵養數據庫

注意: 開始下面以前,請確保你仍然在/YOUR_CODE_DIR/django-drf-react-quickstart/ 目錄。

你可使用 Django fixtures 來填充數據庫。

當你想要給前端一些demo數據時,Fixtures時很是有用的。

建立一個新文件夾: ./leads/fixtures

而後建立一個新的文件: ./leads/fixtures/leads.json 內容爲下面的JSON:

[
    {
        "model": "leads.lead",
        "pk": 1,
        "fields": {
            "name": "mtianyan",
            "email": "1147727180@qq.com",
            "message": "I am a happy pythoner",
            "created_at": "2019-01-07 00:00:00"
        }
    },
    {
        "model": "leads.lead",
        "pk": 2,
        "fields": {
            "name": "Tom",
            "email": "tomsomething@gmail.com",
            "message": "I want to talk about a Python project",
            "created_at": "2018-01-14 00:00:00"
        }
    }
]
複製代碼

保存並關閉這個文件,而後使用下面命令加載fixture:

python manage.py loaddata leads
複製代碼

mark

這就是所有了,下面的部分,咱們將實現一個簡單的React 前端!

譯者添加: xadmin 管理 & drf 在線文檔

安裝

pipenv install https://codeload.github.com/sshwsfc/xadmin/zip/django2
複製代碼

註冊進INSTALL_APP

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'leads',          # 添加leads app
    'rest_framework', # 添加rest framework
    'xadmin',         # 添加 xadmin
    'crispy_forms',   # 添加 xadmin
]
複製代碼

配置URL(django-drf-react-quickstart\drf_react\urls.py):

from django.urls import path, include
import xadmin

urlpatterns = [
    path('', include('leads.urls')),
    path('xadmin/', xadmin.site.urls),
]
複製代碼

添加了xadmin的import 和 xadmin path url mapping。

新建adminx.py(django-drf-react-quickstart\leads\adaminx.py)

import xadmin
from xadmin import views
from .models import Lead
class BaseSetting(object):
	"""xadmin的基礎信息配置"""
	enable_themes = True  # 開啓主題功能
	use_bootswatch = True 

class GlobalSettings(object):
	"""xadmin通用信息配置"""
	site_title = "Leads Xadmin"
	site_footer = "mtianyan@qq.com"

# 註冊設置信息到View
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)

class LeadAdmin(object):
	""" list_display: 後臺展現哪些字段 search_fields: 後臺可搜索哪些字段 list_filter: 後臺過濾器可以使用哪些字段 """
	list_display = ['name', 'email','message']
	search_fields = ['name', 'email','message']
	list_filter = ['name', 'email','message','created_at']

xadmin.site.register(Lead, LeadAdmin)
複製代碼

遷移數據庫:

python manage.py makemigrations
python manage.py migrate
複製代碼

建立後臺管理員

python manage.py createsuperuser
複製代碼

登陸後臺

運行

python manage.py runserver
複製代碼

訪問: http://127.0.0.1:8000/xadmin/

mark

在線api交互文檔

  • 安裝須要的包:
pipenv install coreapi
複製代碼
  • 配置url(django-drf-react-quickstart\drf_react\urls.py)
from django.urls import path, include
import xadmin
from rest_framework.documentation import include_docs_urls # new 

urlpatterns = [
    path('', include('leads.urls')),
    path('xadmin/', xadmin.site.urls),
    path('api/docs/', include_docs_urls(title='Lead 在線API文檔')), # new
]
複製代碼
  • 添加註釋以便在線文檔生成

models.py

from django.db import models

# Create your models here.
class Lead(models.Model):
    name = models.CharField(max_length=100,verbose_name="lead名字", help_text="lead名字")
    email = models.EmailField(verbose_name="郵箱", help_text="郵箱")
    message = models.CharField(max_length=300, verbose_name="信息", help_text="信息")
    created_at = models.DateTimeField(auto_now_add=True,verbose_name="建立時間", help_text="建立時間")
複製代碼

添加verbose_name用於xadmin,help_text用於drf

views.py

class LeadListCreate(generics.ListCreateAPIView):
	""" get: 返回全部已存在的lead對象的列表 post: 建立一個新的lead實例 """
	queryset = Lead.objects.all()
	serializer_class = LeadSerializer
複製代碼
  • 運行:
python manage.py runserver
複製代碼

訪問: http://127.0.0.1:8000/api/docs/

mark

大功告成: 咱們有了一個既有後臺,又提供api,又有在線API文檔的Lead服務啦。

敬請期待下次更新React篇! 敬請期待下次更新React篇! 敬請期待下次更新React篇!

相關文章
相關標籤/搜索