python django + vue 先後端分離

部署環境: 安裝python環境,安裝python3: https://www.python.org/downloads/html

安裝 django:前端

pip install django

使用淘寶的cnpm替代npm,安裝cnpm:vue

npm install -g cnpm --registry=https://registry.npm.taobao.org

構建項目:使用命令新建django項目:node

django-admin startproject projectname

進入projectname目錄,新建應用:python

python manage.py startapp base_app

在項目的settings中更改數據庫(因此,者須若是須要更改就須要安裝mysql)mysql

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'supertrampaidb',
        'HOST': 'localhost',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': 'root',
    }
}

把新建的app加入到settings INSTALLED_APPS中webpack

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

在app的models.py 中建立model,並映射到數據庫中映射命令:web

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

    def __unicode__(self):
        return self.book_name
python manage.py makemigrations base_app
python manage.py migrate

在views.p中編寫接口代碼:vue-router

@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['code'] = 200
    except Exception as e:
        response['msg'] = str(e)
        response['code'] = 500

    return JsonResponse(response)


@require_http_methods(['GET'])
def show_books(reuqest):
    response = {}
    try:
        books = Book.objects.filter()
        response['list'] = json.loads(serializers.serialize('json', books))
        response['msg'] = 'success'
        response['code'] = 200
    except Exception as e:
        response['msg'] = str(e)
        response['code'] = 500
    return JsonResponse(response)

在應用目錄下,新建urls.py文件,把接口添加到路由裏面sql

from django.conf.urls import url
from base_app import views

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

在項目的urls文件中,中應用的urls添加進去。

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^api/', include(base_app.urls)),
    url(r'^$', TemplateView.as_view(template_name='index.html')),
]

啓動服務:

python manage.py runserver

在postman經過以下url測試接口: 127.0.0.1:8000/api/add_book?book_name=bookname 1127.0.0.1:8000/api/show_books

vue項目: 安裝vue-cli

cnpm install -g vue-cli

在項目projectname中建立前端工程:

vue-init webpack vueappname

進入vueappname目錄,安裝vue的node依賴:

1. cnpm install
	2. cnpm install vue-resource
	3. cnpm element-ui

在src/component文件家下新建Home.vue的組件,添加前端頁面代碼以及調用接口代碼

<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 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="queryBook()" 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-column prop="add_time" label="刪除" min-width="100">
            <el-button type="primary" @click="delBook()" style="float:left; margin: 2px;">刪除</el-button>
          </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://127.0.0.1:8000/api/add_book?book_name=' + this.input)
        .then((response) => {
          var res = JSON.parse(response.bodyText)
          if (res.code === 200) {
            this.showBooks()
          } else {
            this.$message.error('新增書籍失敗,請重試')
            console.log(res['msg'])
          }
        })
    },
    showBooks () {
      this.$http.get('http://127.0.0.1:8000/api/show_books')
        .then((response) => {
          var res = JSON.parse(response.bodyText)
          console.log(res)
          if (res.code === 200) {
            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>

在src/router/index.js 中把Home添加到vue-router 路由中

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home

    }
  ]
})

依賴第三方包解決跨域問題:

pip install django-cors-headers

在project settingspy中

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

CORS_ORIGIN_ALLOW_ALL = True

另開啓一個terminal 啓動 :npm run dev 自帶的服務器

構建前端工程:npm run build

整合先後端: 項目的settings.py 文件的TEMPLATES .dirs=vueappname/dist

默認DIRS爲空

'DIRS': ['base_vue/dist'],

增長:項目的settings.py 文件下:

配置靜態文件的路徑

Add for vuejs

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "base_vue/dist/static"),
]

運行項目:python manage.py runserver

一路上遇到的坑: 在前端工程目錄下,執行:cnpm run build 構建完成之後,報錯: 問題: Tip: built files are meant to be served over an HTTP server. Opening index.html over file:// won't work. 解決:npm install -g http-server

問題: DateTimeField、DateField和TimeField三種類型能夠用來建立日期字段,其值分別對應着datetime()、date()、time()三種對象。這三個field有着相同的參數auto_now和auto_now_add,在實際使用中很容易出錯

問題:pip install django socket.timeout: The read operation timed out 解決 pip --default-timeout=100 install django

問題:django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3 解決:在項目的__init__.py 文件中無需配置(多是之前版本的問題,致使須要增長該配置,如今版本迭代,所以無需增長)

問題:django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3 解決:在項目的__init__.py 文件中無需配置(多是之前版本的問題,致使須要增長該配置,如今版本迭代,所以無需增長)

問題:AttributeError: module 'django.forms.forms' has no attribute 'ModelForm' 解決: from django import forms # a from django.forms import Form # b 在導入模塊時,若是有a,b這種狀況的須要分開導入。

問題:AttributeError: 'LoginForm' object has no attribute 'cleaned_data' 解決:若是在XXXForm中獲取了*個字段,在html頁面也須要填寫這麼的字段,不然form.is_valid()==False 提示:出現form.is_valid()返回false的緣由通常是form中的每一個field默認都是required的,若是沒有填,form.is_valid()就會返回false。另外,html中的form中的各個field的name必定要和對應的form類的各個field的name保持一致,這也是一個易錯點。

問題:請問若是一個SQL帶IN語句。例如:select count() from Table1 where Column1 in (a,b,c) and ..;想要使用動態SQL語句,(a,b,c) 爲綁定變量,括號內元素個數不肯定。請問要如何編寫這個動態SQL語句? 解決:select count() from Table1 where FIND_IN_SET('Column1','1,2,3,4')

問題:~~~SyntaxError: invalid syntax File "manage.py", line 16 ) from exc ~~~ 解決:python2 不是使用python manage.py startapp appname 新建應用,而是使用其餘的命令,在lz 的機子上,由於安裝cnpm自動安裝了p2,因此,把p2卸載便可

相關文章
相關標籤/搜索