Vue3+TypeScript+Django Rest Framework 搭建個(gè)人博客(一):框架代碼初始化

本文適合對有 Python 語言有一定基礎(chǔ)的人群,希望利用 Python 做更多有意思的事情,比如搭建個(gè)人博客,記錄自己的所思所想,或者想找一個(gè)項(xiàng)目實(shí)踐前后端分離技術(shù)等等。跟著本文可以了解和運(yùn)行項(xiàng)目,本項(xiàng)目是在 Window 10 Professional 系統(tǒng)下開發(fā)

大家好,我是落霞孤鶩,上一篇介紹了開發(fā)博客的背景、技術(shù)棧,并介紹了如何搭建開發(fā)環(huán)境。這一篇介紹后端和前端的基礎(chǔ)框架代碼初始化,基于Django和Vue初始化項(xiàng)目框架代碼,跑通Hello world。

一、后端框架代碼搭建

后端 Python 代碼通過 PyCharm 能比較快速的搭建 Django 項(xiàng)目,因?yàn)樵?PyCharm 的專業(yè)版里面,已經(jīng)內(nèi)置了 Django 框架

1.1 通過 PyCharm 初始化 Django 項(xiàng)目

  1. 通過 pip 安裝Django

為了更好的兼容性,我們自己安裝 Django 2 版本,不采用最新版本。在命令行輸入如下命令:

pip install django==2.2.23
  1. PyCharm 的首屏界面,點(diǎn)擊 New Project 對話框,在左側(cè)選擇 Django,在右側(cè)的 Location中選擇項(xiàng)目地址,項(xiàng)目命令為Blog 并將我們之前安裝的 Python 路徑選擇為 Interpreter ,如下圖:

<img src="https://gitee.com/Zhou_Jimmy/images/raw/master/img/image-20210717165800189.png" alt="image-20210717165800189"/>

  1. 點(diǎn)擊Create,等待 PyCharm 執(zhí)行創(chuàng)建。

如果選擇的 Python Interpreter 環(huán)境中沒有安裝 DjangoPyCharm 會自動安裝 Django 最新版本,由于我們已經(jīng)安裝了Django,PyCharm 會自動使用環(huán)境中的 Django 版本

完成后左側(cè)的導(dǎo)航區(qū)域會自動生成Django框架項(xiàng)目所需的文件,結(jié)構(gòu)如下圖:

image-20210717170550892
  1. Pycharm 右下角點(diǎn)擊 Terminal,通過 pip 安裝 Django Rest Framework
pip install djangorestframework==3.12.4
  1. 驗(yàn)證框架是否可以運(yùn)行

運(yùn)行點(diǎn)擊 PyCharm 右上角的運(yùn)行按鈕,如果正常,在PyCharm的運(yùn)行控制臺會打印如下信息

Performing system checks...

Watching for file changes with StatReloader
System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
July 17, 2021 - 17:42:28
Django version 2.2.23, using settings 'project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

打開 Edge 或 Chrome 瀏覽器,輸入 http://127.0.0.1:8000,回車,如下圖,說明框架搭建成功

image-20210717201616697

1.2 配置 Django Rest Framework

  1. 啟用 Django Rest Framework

    Blog 文件夾下,打開 settings.py 文件,在 INSTALLED_APPSlist 中增加 rest_framework

    INSTALLED_APPS = [
        'django.contrib.admin',  
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',
    ]
    
  2. settings.py 中增加 Rest Framework 的配置

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

1.3 配置 Sqlite 數(shù)據(jù)庫

  1. 在項(xiàng)目路徑下,創(chuàng)建data文件夾
  2. settings.py 中修改 DATABASESdefault 下的 NAME 的值,增加 data 路徑,接入如下
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'data/db.sqlite3'),
    }
}

1.4 調(diào)整項(xiàng)目結(jié)構(gòu)

  1. 修改 Blog 文件夾名稱為 project

通過 PyCharm 自動生成的項(xiàng)目結(jié)構(gòu),會自動生成一個(gè)和項(xiàng)目名稱一樣的子文件夾,為了有效的組織后端的各個(gè)模塊,這里我們將自動生成的 Blog 文件夾修改為 project

操作如圖:

<img src="https://gitee.com/Zhou_Jimmy/images/raw/master/img/image-20210716174351302.png" alt="image-20210716174351302" style="zoom:50%;" />

<img src="https://gitee.com/Zhou_Jimmy/images/raw/master/img/image-20210716174434089.png" alt="image-20210716174434089" style="zoom:50%;" />

點(diǎn)擊 Refector,然后點(diǎn)擊左下角的 Do Refector 完成修改。

<img src="https://gitee.com/Zhou_Jimmy/images/raw/master/img/image-20210716174553811.png" alt="image-20210716174553811" style="zoom:50%;" />

  1. settings.py 文件中,將 ROOT_URLCONF 中的 Blog 修改為 project
ROOT_URLCONF = 'project.urls'
  1. settings.py 文件中,將 TEMPLATES 中的 DIRS 的值修改為 [BASE_DIR + '/templates']
TEMPLATES = [    
  {        
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR + '/templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
      },
  },
]
  1. 創(chuàng)建 common APP,在 terminal 中輸入如下命令:
python manage.py startapp common
  1. 完成后,整個(gè)項(xiàng)目結(jié)構(gòu)如下圖:
image-20210717173357712

1.5 編寫 User 對象的 API

  1. common/models.py 中編寫基礎(chǔ)模型抽象類 AbstractBaseModel

用來幫助構(gòu)建所有業(yè)務(wù)模型自動增加創(chuàng)建人,創(chuàng)建時(shí)間,修改人,修改時(shí)間

from django.contrib.auth.models
import AbstractUserfrom django.db import models


class AbstractBaseModel(models.Model):
    creator = models.IntegerField('creator', null=True)
    created_at = models.DateTimeField(verbose_name='Created at', auto_now_add=True)

    modifier = models.IntegerField('modifier', null=True)
    modified_at = models.DateTimeField(verbose_name='Modified at', auto_now=True)

    class Meta:
        abstract = True

其中兩個(gè)屬性的入?yún)⑿枰f明

  • auto_now_add=True 表示在新增的時(shí)候,自動將該字段的值設(shè)置為當(dāng)前時(shí)間

  • auto_now=True 表示在記錄更新的時(shí)候,自動設(shè)置為當(dāng)前時(shí)間

  • abstract = True 表示該類是抽象類,不需要生成物理模型

  1. common/models.py 中重寫User

由于我們需要在博客中記錄注冊用戶的昵稱,頭像等擴(kuò)展信息,因此 Django 自帶的User 模型字段無法滿足,所以通過集集成Django 提供的 AbstractUser 來擴(kuò)展,通過Meta類中定義我們想要的表名 blog_user

class User(AbstractUser, AbstractBaseModel):
    avatar = models.CharField('頭像', max_length=1000, blank=True)
    nickname = models.CharField('昵稱', null=True, blank=True, max_length=200)
    
    class Meta(AbstractUser.Meta):
        db_table = 'blog_user'
        swappable = 'AUTH_USER_MODEL'

如果我們不單獨(dú)定義,則會用 Django 中設(shè)定的表名,這樣不利于我們有效的識別和管理數(shù)據(jù)庫中的表

  1. common 下新增 serializers.py ,在serializers.py 中新增類 UserSerialiazer,繼承 Rest Framework 提供的 serializers.ModelSerializer
from rest_framework import serializers
from common.models import User


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'avatar', 'email', 'is_active', 'created_at',  'nickname']

這里定義需要在 API 接口中出現(xiàn)的字段,包括新增、修改、查詢接口字段。

  1. common/views.py 文件中,編寫 UserViewSet 類,繼承 Rest Framework 提供的 viewsets.ModelViewSet
from rest_framework import viewsets, permissions
from common.models import User
from common.serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all().order_by('username')
    serializer_class = UserSerializer
    permission_classes = [permissions.AllowAny]

這里只需要 Override 三個(gè)類屬性,查詢集合 queryset、序列器類 serialiazer_class,權(quán)限校驗(yàn) permission_classes

我們這里設(shè)置權(quán)限校驗(yàn)為 AllowAny,表示這個(gè)對象下的接口可以不用登錄就可以訪問,這么做的目的是為了下面測試接口的連通性。

  1. 修改 project/settings.py 配置

INSTALL_APPS 中增加 common

INSTALLED_APPS = [
    'django.contrib.admin',  
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'common',
]

新增一行代碼,定義User 鑒權(quán)對應(yīng)的模型,因?yàn)槲覀兏膶懙哪J(rèn)的 User

# User
AUTH_USER_MODEL = 'common.User'
  1. 定義 API 路由規(guī)則

common 下新增urls.py 中,并增加如下代碼,這里需要定義 app_name = 'common',用于路由 Rest Framework 區(qū)別路由

from rest_framework import routers
from django.urls import include, path
from common import views

router = routers.DefaultRouter()
router.register('user', views.UserViewSet)

app_name = 'common'

urlpatterns = [
    path('', include(router.urls)),
]

project/url 中引入 common APP中的路由,并加入 Rest Framework 用戶鑒權(quán)路由api-auth/

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
        path('admin/', admin.site.urls),
    path('', include('common.urls', namespace='common')),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

1.6 模型遷移和配置

  1. 通過Django 做模型遷移

PyCharm 提供的 Terminal 中輸入如下命令,完成模型創(chuàng)建

python manage.py makemigrations
# Migrations for 'common':
#  common\migrations\0001_initial.py
#    - Create model User
python manage.py migrate
# Operations to perform:
#   Apply all migrations: admin, auth, common, contenttypes, sessions
# Running migrations:
#   Applying contenttypes.0001_initial... OK
#   Applying contenttypes.0002_remove_content_type_name... OK
#   Applying auth.0001_initial... OK
#   Applying auth.0002_alter_permission_name_max_length... OK
#   Applying auth.0003_alter_user_email_max_length... OK
#   Applying auth.0004_alter_user_username_opts... OK
#   Applying auth.0005_alter_user_last_login_null... OK
#   Applying auth.0006_require_contenttypes_0002... OK
#   Applying auth.0007_alter_validators_add_error_messages... OK
#   Applying auth.0008_alter_user_username_max_length... OK
#   Applying auth.0009_alter_user_last_name_max_length... OK
#   Applying auth.0010_alter_group_name_max_length... OK
#   Applying auth.0011_update_proxy_permissions... OK
#   Applying common.0001_initial... OK
#   Applying admin.0001_initial... OK
#   Applying admin.0002_logentry_remove_auto_add... OK
#   Applying admin.0003_logentry_add_action_flag_choices... OK
#   Applying sessions.0001_initial... OK
  1. 配置數(shù)據(jù)庫管理工具

這個(gè)時(shí)候,可以在 data 文件下看到生成的 Sqlite 數(shù)據(jù)庫文件 db.sqlite3,和我們在 project/settings.pyDATABASE 中定義的名稱一致。

image-20210717200523546

雙擊這個(gè)文件,PyCharm 會自動在右側(cè)的 Database 工具類中創(chuàng)建一個(gè) Sqlite 的數(shù)據(jù)庫記錄。點(diǎn)擊下圖中表紅的按鈕,進(jìn)入數(shù)據(jù)庫配置頁面。

image-20210717195549453

點(diǎn)擊下方的 Download missing driver files,下載 Sqlite 驅(qū)動,修改 nameblog,在Schemas 標(biāo)簽頁中,勾選 All shemas,點(diǎn)擊確定。

image-20210717195453923

然后右側(cè)就出現(xiàn)了我們剛剛通過 migrate 命令生成的表:

image-20210717200126701

標(biāo)紅的表就是我們在 common/models.py 中定義的 User 類映射出來的表,其他的表是 Django 框架內(nèi)置的表,主要用在管理權(quán)限,Session,日志等。

1.7 創(chuàng)建管理員賬號

這里通過 Django 自帶的命令完成管理員賬號的創(chuàng)建,在 PyCharm 提供的 Terminal 中,輸入如下命令:

python manage.py createsuperuser --email admin@example.com --username blog-admin
# Password:
# Password (again):
# Superuser created successfully.

依據(jù)提示輸入密碼 12345678.Abc,確認(rèn)輸入密碼,回車,完成管理員賬號的創(chuàng)建

1.8 測試API

  1. 點(diǎn)擊 PyCharm 右上角的運(yùn)行按鈕
image-20210717201808127
  1. 打開瀏覽器,在地址欄中輸入 http://127.0.0.1:8000/

看到如下界面,說明API配置已經(jīng)成功

image-20210717201333539
  1. 測試用戶查詢接口

點(diǎn)擊上圖中的 http://127.0.0.1:8000/user/

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "user": "http://127.0.0.1:8000/user/"
}

得到如下圖界面,說明接口已經(jīng)完全編寫成功,恭喜你,記得給你自己一個(gè)大拇指哦

image-20210717201959887

1.9 Django Rest Framework 官方英文示例教程

https://www.django-rest-framework.org/tutorial/quickstart/

二、前端框架代碼搭建

在介紹篇,我們已經(jīng)安裝了 Vite,這里我們就通過 Vite 來初始化 Vue 的項(xiàng)目

2.1 通過 Vite 初始化 Vue 項(xiàng)目

  1. C:\Users\Administrator 路徑下,創(chuàng)建文件夾 VSCodeProjects
cd C:\Users\Administrator
mkdir VSCodeProjects
  1. VscodeProjects 文件夾下創(chuàng)建 blog 項(xiàng)目
cd VSCodeProjects
yarn create vite blog --template vue-ts
  1. VS Code 項(xiàng)目

打開 C:\Users\Administrator\VSCodeProjects\Blog 文件夾,可以看到,通過 Vite 模板,已經(jīng)幫我們生成好了所有基礎(chǔ)文件,包括 TypeScript 相關(guān)的依賴和 shims 文件。

image-20210717223043228

2.2 依賴安裝

  1. 安裝 Less 依賴

這里的 -D 參數(shù)表示是在開發(fā)階段的依賴,上線運(yùn)行時(shí)不需要該依賴。

yarn add less@4.1.1 -D
  1. 安裝 Element-Plus 依賴
yarn add element-plus
  1. 安裝基礎(chǔ)依賴,并運(yùn)行

在 VS Code 中,通過快捷鍵 Ctrl + J 打開 Terminal,輸入如下命令:

yarn
yarn dev
# yarn run v1.22.10
# warning package.json: No license field
# $ vite
# [vite] Optimizable dependencies detected:
# vue
# 
#   Dev server running at:
#   > Network:  http://192.168.2.14:3000/
#   > Local:    http://localhost:3000/
  1. 在瀏覽器中輸入地址 http://localhost:3000/, 效果如下
image-20210717223231841

三、前后端代碼聯(lián)調(diào)

前后端聯(lián)調(diào)時(shí),需要先在前端配置路由,Vite 代理,Axios 網(wǎng)絡(luò)請求。

3.1 配置 Axios

  1. 安裝 Axios ,在 VS Code 的Terminal 中執(zhí)行命令
yarn add axios
  1. 配置 vite.config.ts

在項(xiàng)目根目錄下,修改 vite.config.ts,代碼如下:

import vue from '@vitejs/plugin-vue'
import {defineConfig} from 'vite'


export default defineConfig({
    plugins: [
        vue(),
     ],

    base: '/',

    server: {
        host: "localhost",
        port: 3000,
        proxy: {
            '/api': {
                target: 'http://localhost:8000/',
                changeOrigin: true,
                ws: false,
                rewrite: (pathStr) => pathStr.replace('/api', ''),
                timeout: 5000,
            },
        },
    }
});
  1. 配置 Axios 實(shí)例

src 目錄下,新建文件夾 api,在 api 下新建文件 index.ts,編寫如下代碼:

import axios, {AxiosRequestConfig, AxiosResponse} from "axios";

const request = axios.create({
    baseURL: import.meta.env.MODE !== 'production' ? '/api' : '',
})

export default request;
  1. 編寫請求接口的代碼

api 下新建文件 service.ts,編寫如下代碼:

import request from "./index";

export function getUserList(params: any) {
    return request({
        url: '/user/',
        method: 'get',
        params,
    })
}

3.2 創(chuàng)建用戶列表頁面

修改在 src 下創(chuàng)建 App.vue ,在文件里面編寫如下代碼,獲取用戶列表的接口調(diào)用,調(diào)用后得到的數(shù)據(jù)加載到表格中展示,同時(shí)通過分頁展示列表。

<template>
  <div>
    <div>
      <el-table
        :data="state.userList"
        :header-cell-style="{ background: '#eef1f6', color: '#606266' }"
        stripe
      >
        <el-table-column type="selection" width="55" />
        <el-table-column label="ID" prop="id" width="80" />
        <el-table-column label="賬號" prop="username" width="200" />
        <el-table-column label="昵稱" prop="nickname" width="200" />
        <el-table-column label="狀態(tài)" prop="is_active" />
      </el-table>
    </div>
    <div class="pagination">
      <el-pagination
        :page-size="10"
        :total="state.total"
        background
        layout="prev, pager, next"
      ></el-pagination>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive } from "vue";
import { getUserList } from "./api/service";

export default defineComponent({
  name: "App",
  setup: function () {
    const state = reactive({
      userList: [],
      params: {
        page: 1,
        page_size: 10,
      },
      total: 0,
    });

    const handleSearch = async (): Promise<void> => {
      try {
        const data: any = await getUserList(state.params);
        state.userList = data.data.results;
        state.total = data.data.count;
      } catch (e) {
        console.error(e);
      }
    };

    handleSearch();
    return {
      state,
      handleSearch,
    };
  },
});
</script>

<style scoped>
.pagination {
  text-align: right;
  margin-top: 12px;
}
</style>

3.3 配置 Router

  1. 安裝 vue-router ,在 VS Code 的Terminal 中執(zhí)行命令
yarn add vue-router@next
  1. 配置 route

在項(xiàng)目 src 目錄下面新建 route 目錄,并添加 index.ts 文件,文件中添加以下內(nèi)容

import {createRouter, createWebHistory, RouteRecordRaw} from "vue-router";
import App from "../App.vue";

const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        name: "User",
        component: App,
        meta: {}
    },
]

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
});


export default router;

3.4 調(diào)整 main.ts

增加 Element-Plus的組件,加載 router,代碼如下:

import { createApp } from 'vue'
import App from './App.vue'
import router from "./route";
import {
    ElPagination,
    ElTable,
    ElTableColumn
} from 'element-plus';

const app = createApp(App)

app.component(ElTable.name, ElTable);
app.component(ElTableColumn.name, ElTableColumn);
app.component(ElPagination.name, ElPagination);


app.use(router).mount('#app')

3.5 測試界面

  1. 在 PyCharm 中啟動后端服務(wù)
  2. 在 VS Code 中啟動前端
yarn dev
  1. 在瀏覽器中輸入http://127.0.0.1:8080 得到如下效果
image-20210718175955373

到這一步,我們已經(jīng)完成了前后端聯(lián)調(diào),第一個(gè)接口已經(jīng)通過界面方式完成調(diào)用和數(shù)據(jù)展示,給自己一個(gè)贊哦。

四、代碼納入Git 版本管理

還記得我們在第一篇文章中創(chuàng)建的代碼倉庫吧,現(xiàn)在我們要把剛剛創(chuàng)建的前端代碼和后臺代碼提交到代碼倉庫中。

這里以后端為例,我之前是在Gitee上創(chuàng)建了一個(gè)公開倉庫:https://gitee.com/Zhou_Jimmy/blog-backend.git,現(xiàn)在就把后端代碼提交到這個(gè)倉庫中。

命令在 PyCharm 提供的 Terminal 中輸入

4.1 配置本地的 git 信息

git config --global user.name "Zhou_Jimmy"
git config --global user.email "331352343@qq.com"

在設(shè)置的時(shí)候記得修改成你自己的名字和郵箱哦

4.2 本地代碼初始化git

git init
# Initialized empty Git repository in C:/Users/Administrator/PycharmProjects/Blog/.git/
git remote add origin https://gitee.com/Zhou_Jimmy/blog-backend.git

在設(shè)置的時(shí)候,記得修改成你自己的倉庫地址

4.3 拉取遠(yuǎn)程倉庫上的代碼

git pull origin master

4.4 建立忽略文件

在項(xiàng)目根路徑下增加或編輯 .gitignore 文件,忽略不用加入到版本管理的文件,文件中的內(nèi)容可以參考 Gitee 或 GitHub 提供的模板,這里主要增加 PyCharm 配置信息的文件夾

.idea

如果是前端代碼,則增加這么一行

.vscode

4.5 提交代碼

4.5.1 通過 Git 命令提交

可以通過如下命令完成提交,最后需要你輸入倉庫賬號和密碼,完成后,代碼就提交到了遠(yuǎn)程倉庫了。

git add .
git commit -m "Django框架初始化代碼提交"
git push origin master

4.5.2 通過 PyCharm 界面功能提交

可以點(diǎn)擊 PyCharm 右上角的提交按鈕

image-20210717205924922

點(diǎn)擊后,左側(cè)出現(xiàn)提交文件選擇框,勾選文件,并填寫comment,點(diǎn)擊 Commit and Push 按鈕,完成提交。

image-20210717210041771

后端提交完成后,遠(yuǎn)程倉庫效果如下:

image-20210717210532928

前端提交完成后,遠(yuǎn)程倉庫效果如下:

image-20210718181424047
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容