python django framework + разделение внешнего и внутреннего интерфейса vue.js

Python

Это 6-й день моего участия в Gengwen Challenge.Подробности мероприятия смотрите:Обновить вызов

Эта статья используется для изучения django+vue.js для достижения разделения веб-интерфейса и серверной части и совместной разработки. В качестве примера возьмем приложение книги добавления и удаления базы данных.

Официальный адрес фреймворка Django:www.djangoproject.com/

Официальный адрес фреймворка vue.js:cn.vuejs.org/

1. Соберите проект django

1. Создайте файлы проекта и приложение

Создать django_vue

django-admin startproject django_vue

Введите django_vue и создайте виртуальную среду django_vue_env.

pip install virtualenv  #安装
virtualenv django_vue_env

Активируйте виртуальную среду и установите django

source ./django_vue_env/bin/activate

Установите django, django-cors-headers (междоменные), используемые позже, запросы

image-20210616220115778

Создайте приложение джанго

python manage.py startapp app

Наш каталог должен быть таким, appfront будет создан позже для проекта vue.

image-20210616220759863

Для базы данных мы можем использовать sqlite3 по умолчанию, Если вам нужно изменить его, вы можете настроить базы данных в settings.py.

image-20210616221036093

Добавьте приложения в INSTALLED_APPS

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

Добавьте модель базы данных, включая book_name и add_time, чтобы записать название книги и добавить время.

from django.db import models



# Create your models here.
class Book(models.Model):
    book_name = models.CharField(max_length=64)
    add_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.book_name

выполнить миграцию базы данных

python manage.py makemigrations app
python manage.py migrate

Напишите views.py, чтобы добавить два API-интерфейса, show_books и add_book, и вернуть данные запроса через JsonResponse.

from django.shortcuts import render

# Create your views here.
# 需要导入相关的模块
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.core import serializers
import requests
import json

from .models import Book

@require_http_methods(["GET"])
def add_book(request):
    response = {}
    try:
        book = Book(book_name=request.GET.get('book_name'))
        book.save()
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1

    return JsonResponse(response)

@require_http_methods(["GET"])
def show_books(request):
    response = {}
    try:
        books = Book.objects.filter()
        response['list']  = json.loads(serializers.serialize("json", books))
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1

    return JsonResponse(response)

Добавьте маршрут API в urls.py в каталоге django_vue.

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include(app.urls)),
]

Добавьте маршрут просмотра в urls.py в каталоге приложения.

from django.urls import path,re_path
# 导入 myapp 应用的 views 文件
from . import views

urlpatterns = [
    re_path(r'add_book$', views.add_book),
    re_path(r'show_books$', views.show_books)
]

Перезапустите службу и используйте команду curl, чтобы проверить доступность API. Следующие интерфейсы являются нормальными.

 python manage.py runserver
 
 curl  http://127.0.0.1:8000/api/add_book?book_name=mylife
 
 {"msg": "success", "error_num": 0}
 
 curl  http://127.0.0.1:8000/api/show_books
 
 {"list": [ {"model": "app.book", "pk": 9, "fields": {"book_name": "mylife", "add_time": "2021-06-16T14:44:49.230Z"}}], "msg": "success", "error_num": 0}

Серверная часть django примерно построена, а внешний интерфейс vue находится рядом.


1. Создайте проект vue

Установите инструмент командной строки для инициализации vuevue-cli

npm install -g vue-cli

Соберите интерфейсный проект в каталоге django_vue.appfront, который содержит инструменты веб-пакета.

vue-init webpack appfront

Каталог appfront выглядит следующим образом

image-20210616231328773

установить рендерelement-ui,vue-resource

npm install element-ui
npm install vue-resource

Настройте src/main.js следующим образом.

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import VueResource from 'vue-resource'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(VueResource)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

существуетsrc/componentновый каталогHome.vue,ВключаютshowBooksиaddBookДля запроса API используются два метода.

<template>
  <div class="home">
    <el-row display="margin-top:10px">
        <el-input v-model="input" placeholder="请输入书名" style="display:inline-table; width: 30%; float:left"></el-input>
        <el-button type="primary" @click="addBook()" style="float:left; margin: 2px;">新增</el-button>
    </el-row>
    <el-row>
        <el-table :data="bookList" style="width: 100%" border>
          <el-table-column prop="id" label="编号" min-width="100">
            <template scope="scope"> {{ scope.row.pk }} </template>
          </el-table-column>
          <el-table-column prop="book_name" label="书名" min-width="100">
            <template scope="scope"> {{ scope.row.fields.book_name }} </template>
          </el-table-column>
          <el-table-column prop="add_time" label="添加时间" min-width="100">
            <template scope="scope"> {{ scope.row.fields.add_time }} </template>
          </el-table-column>
        </el-table>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'home',
  data () {
    return {
      input: '',
      bookList: [],
    }
  },
  mounted: function() {
      this.showBooks()
  },
  methods: {
    addBook(){
      this.$http.get('http://139.198.114.148:8000/api/add_book?book_name=' + this.input)
        .then((response) => {
            var res = JSON.parse(response.bodyText)
            if (res.error_num == 0) {
              this.showBooks()
            } else {
              this.$message.error('新增书籍失败,请重试')
              console.log(res['msg'])
            }
        })
    },
    showBooks(){
      this.$http.get('http://139.198.114.148:8000/api/show_books')
        .then((response) => {
            var res = JSON.parse(response.bodyText)
            console.log(res)
            if (res.error_num == 0) {
              this.bookList = res['list']
            } else {
              this.$message.error('查询书籍失败')
              console.log(res['msg'])
            }
        })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

Мы решаем проблемы с перекрестным происхождением через django-cors-headers.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
    'corsheaders',  //添加app
]

Добавить промежуточное ПОcorsheaders.middleware.CorsMiddleware

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Настройте междоменные правила в settings.py.

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)
  
CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

npm run devзапустить узел сервера

image-20210616232921950

пройти черезnpm run buildУпакуйте внешний интерфейс в каталог dist для последующих ссылок django.


3. Django ссылается на внешний интерфейс

Настройте маршрутизацию urls.py в каталоге django_vue следующим образом.

from django.contrib import admin
from django.urls import path,include
from django.views.generic import TemplateView  //导入通用视图
import app.urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include(app.urls)),
    path('',TemplateView.as_view(template_name="index.html")), //路由到index.html
]

Добавить статический адрес файла в settings.py

STATICFILES_DIRS = [(os.path.join(BASE_DIR,'appfront/dist/static'))] 

запустить службу джанго

python manage.py runserver

Посетите наш адрес django, на данный момент django связан с внешним интерфейсом

image-20210616234100999


Ссылаться на:GitHub.com/Роджер Л.Х./Все…

NEXT

  • django-rest-framework создает спокойный API
  • джанго wsgi приложение

Если в статье есть недостатки, просьба указать их в комментариях.

Лайки, лайки и вопросы приветствуются. Следуйте за топ-менеджерами водораздатчиков, которые иногда занимаются чем-то другим, кроме горячей воды.