图书管理系统(view)前后端调联 (copy)

使用view Djang接口

  1. books/view

    1. 注册

    2. INSTALLED_APPS = [
          'books.apps.BooksConfig',
      
          'corsheaders',
          'rest_framework',
          'django_filters',
      
      ]
      
    3. 配置跨域

    4. #1.添加cors  注销csrf
      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',
      ]
      
      
      #2.添加
      CORS_ALLOW_CREDENTIALS = True
      CORS_ORIGIN_ALLOW_ALL = True
      CORS_ORIGIN_WHITELIST = (
          'http://127.0.0.1:8080',
          'http://localhost:8080',
      )
      
  2. books/models

    1. from django.db import models
      
      
      # Create your models here.
      
      class Book(models.Model):
          name = models.CharField(max_length=32)
          price = models.IntegerField()
          datatime = models.DateTimeField(auto_now=True)
          browse = models.IntegerField(default=0)
      
          class Meta:
              db_table = "图书"
      
  3. 迁移数据库

    1. python  manage.py makemigrations
      python manage.py  migrate
      
  4. books/views(使用View)

    1. import json
      
      from django.http import JsonResponse, HttpResponse
      from django.shortcuts import render
      from django.views import View
      from rest_framework.response import Response
      from rest_framework.views import APIView
      from .serializers import *
      from .models import *
      
      
      # 使用View
      
      # Create your views here.
      
      # 测试跨域
      class BooksShowView2(APIView):
          def post(self, request):
              print(request.data)
      
      
      # 获取所有图书
      class BooksShowView(View):
          def get(self, request):
              # ser = BookSerializer(Book.objects.all().values(),many=True)
              # return HttpResponse(ser.data)
              # print(list(Book.objects.all().values()))
      
              return JsonResponse(list(Book.objects.all().values()), safe=False)
      
          # 添加接口
          def post(self, request):
              # 使用request.body接收数据  decode解码  json.loads变格式
              print(request.body)
              # b'{"name":"12333333","datetime":"","price":100,"browse":0}'
              # print(request.body.decode())
              # {"name": "12333333", "datetime": "", "price": 100, "browse": 0}
              print(json.loads(request.body.decode()))
              # {'name': '12333333', 'datetime': '', 'price': 100, 'browse': 0}
      
              data = json.loads(request.body.decode())
      
              name = data.get("name")
              price = data.get("price")
              browse = data.get("browse")
      
              instance = {"name": name, "price": price, "browse": browse}
              que = Book.objects.create(**instance)
              que.save()
              return HttpResponse("添加成功")
      
      
      # 修改
      class BooksApiView(View):
      
          def post(self, request):
              data = json.loads(request.body.decode())
      
              name = data.get("name")
              price = data.get("price")
              browse = data.get("browse")
              pk = data.get("id")
      
              instance = {"name": name, "price": price, "browse": browse}
              Book.objects.filter(pk=pk).update(**instance)
              return HttpResponse("修改成功")
      
      
      # 删除 
      def delbook(request):
          data = json.loads(request.body.decode())
          print(data)
      
          pk = data.get("id")
          print(pk)
          Book.objects.filter(pk=pk).delete()
          return HttpResponse("删除成功")
      
      
  5. books/urls

    1. from django.urls import path
      from .views import *
      
      
      urlpatterns = [
          path('book/', BooksShowView.as_view()),  # 展示  添加
          path('upbooks/', BooksApiView.as_view()),  # 修改
          path('delbooks/', delbook),  # 删除  
      ]
      

Vue页面

  1. 下载axios@0.19.2 下载element-ui

    1. cnpm install --save axios@0.19.2
    2. cnpm install --save element-ui
      1. src/main.js引用全局
      2. //element
        import ElementUI from 'element-ui'
        import 'element-ui/lib/theme-chalk/index.css'
        Vue.use(ElementUI)
        
  2. 配置跨域

    1. 在http/index.js

    2. import axios from 'axios'
      // axios.defaults.baseURL = "http://127.0.0.1:8000/"
      axios.defaults.baseURL = "http://192.168.56.100:8888/"
      
      
      //全局设置网络超时
      axios.defaults.timeout = 10000;
      
      //设置请求头信息
      axios.defaults.headers.post['Content-Type'] = 'application/json';
      axios.defaults.headers.put['Content-Type'] = 'application/json';
      
      
      axios.interceptors.request.use(
        config => {
          // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
          const token = localStorage.getItem("token")
          // console.log(token)
          if (token) {
            config.headers.Authorization = 'JWT ' + token
          }
          return config;
        },
        error => {
          return Promise.error(error);
        })
      
      
      axios.interceptors.response.use(
        // 请求成功
        res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
      
        // 请求失败
        error => {
          if (error.response) {
            // 判断一下返回结果的status == 401?  ==401跳转登录页面。  !=401passs
            // console.log(error.response)
            if (error.response.status === 401) {
              // 跳转不可以使用this.$router.push方法、
              // this.$router.push({path:'/login'})
              window.location.href = "http://127.0.0.1:8080/"
            } else {
              // errorHandle(response.status, response.data.message);
              return Promise.reject(error.response);
            }
            // 请求已发出,但是不在2xx的范围
          } else {
            // 处理断网的情况
            // eg:请求超时或断网时,更新state的network状态
            // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
            // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
            // store.commit('changeNetwork', false);
            return Promise.reject(error.response);
          }
        });
      
      
      // 封装xiaos请求
      
      // 封装get请求
      export function axios_get(url, params) {
        return new Promise(
          (resolve, reject) => {
            axios.get(url, {params: params})
              .then(res => {
                // console.log("封装信息的的res", res)
                resolve(res.data)
              }).catch(err => {
              reject(err.data)
            })
          }
        )
      }
      
      // 封装post请求
      export function axios_post(url, data) {
        return new Promise(
          (resolve, reject) => {
            // console.log(data)
            axios.post(url, JSON.stringify(data))
              .then(res => {
                // console.log("封装信息的的res", res)
                resolve(res.data)
              }).catch(err => {
              reject(err.data)
            })
          }
        )
      }
      
      // 封装put请求
      export function axios_put(url, data) {
        return new Promise(
          (resolve, reject) => {
            // console.log(data)
            axios.put(url, JSON.stringify(data))
              .then(res => {
                // console.log("封装信息的的res", res)
                resolve(res.data)
              }).catch(err => {
              reject(err.data)
            })
          }
        )
      }
      
      // 封装delete请求
      export function axios_delete(url, data) {
        return new Promise(
          (resolve, reject) => {
            // console.log(data)
            axios.delete(url, {params: data})
              .then(res => {
                // console.log("封装信息的的res", res)
                resolve(res.data)
              }).catch(err => {
              reject(err.data)
            })
          }
        )
      }
      
    3. 在http/apis.js

    4. /* eslint-disable */
      
      import {axios_get, axios_post, axios_delete, axios_put} from './index.js'
      
      //事例
      // export const getBookList = (params, headers) => axios_get("/books/book/", params, headers)
      export const ce = (params, headers) => axios_get("/user/c/", params, headers)
      export const getBookList = (params, headers) => axios_get("/books/book/", params, headers)
      export const updateBook = (params, headers) => axios_post("/books/upbooks/", params, headers)
      export const addBook = (params, headers) => axios_post("/books/book/", params, headers)
      export const delBook = (params, headers) => axios_post("/books/delbooks/", params, headers)
      
  3. views/book-manage

    1. <template>
        <div>
          <h1>图书管理系统 {{ dialogVisible }}</h1>
          <div style="margin: 30px;">
            <button @click="addNew">新增图书</button>
            <BookEdit2
              v-show='dialogVisible'
              :visible.sync='dialogVisible'
              :data='editData'
              @save='save'
            ></BookEdit2>
          </div>
      
          <div>
            <table style='margin: auto; border: solid 1px black;'>
              <tr>
                <th>图书编号</th>
                <th>图书名字</th>
                <th>出版时间</th>
                <th>阅读数</th>
                <th>评论数</th>
                <th>操作</th>
              </tr>
              <tr
                v-for="(book, index) in books"
                :key="book.id"
              >
                <td>{{ book.id }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.datatime }}</td>
                <td>{{ book.price }}</td>
                <td>{{ book.browse }}</td>
                <td>
                  <button @click="edit(book)">修改</button>
                  <button @click="del(book.id)">删除</button>
                </td>
              </tr>
            </table>
          </div>
      
        </div>
      </template>
      
      <script>
      import {getBookList, addBook, updateBook, delBook} from '../../http/apis'
      
      import BookEdit2 from './components/BookEdit2'
      
      export default {
        components: {
          BookEdit2,
        },
        data() {
          return {
            dialogVisible: false,
            books: [],
            editData: {  // 编辑的内容
              name: "",
              datetime: "",
              price: 0,
              browse: 0
            }
          }
        },
        methods: {
          // 1.点击新增图书时初始化数据
          addNew() {
            this.editData = {  // 初始化 编辑内容
              name: "",
              datetime: "",
              price: 100,
              browse: 0
            }
            this.dialogVisible = true  // 显示弹框
          },
      
          // 2.获取图书列表
          get() {
            getBookList().then((data) => {
              console.log(data)
              // books: [{btitle: "西游记", bpub_date: "2020-08-11", bread: 100, bcomment: 50}]
              this.books = data
            })
          },
      
          // 3.修改或者添加图书
          save() {
            // 根据editData中的id判断是更新还是新增
            // debugger
            console.log(this.editData)
            if (this.editData.id) {
              // 如果有id, 修改图书
              // 修改请求
              let params = this.editData
              updateBook(params).then((res) => {
                console.log(res)
                this.get()
              })
            } else {
              // 增加图书
              console.log(this.editData)
              addBook(this.editData).then((res) => {
                console.log(res)
                this.get()
              })
            }
          },
      
          // 点击修改弹出修改页面
          edit(book) {
            this.editData = book
            this.dialogVisible = true
          },
      
          // 删除
          del(book_id) {
            let params = {
              id: book_id
            }
            delBook(params).then((res) => {
              console.log(res)
              this.get()
            })
          }
        },
        created() {
          this.get()
        }
      }
      </script>
      
      <style>
      table tr td {
         150px;
        border: solid 1px black;
      }
      </style>
      
  4. views/book-manage/components

    1. <template>
        <div>
          <el-dialog
            title="新增图书"
            :visible="visible"
          >
            <div><span>图书名称:</span>
              <el-input
                class='elinput'
                v-model="data.name"
              ></el-input>
            </div>
            <div><span>发布日期:</span>
              <el-input
                class='elinput'
                v-model="data.datetime"
              >
              </el-input>
            </div>
            <div><span>阅读量:</span>
              <el-input
                class='elinput'
                v-model="data.price"
              ></el-input>
            </div>
            <div><span>评论量:</span>
              <el-input
                class='elinput'
                v-model="data.browse"
              ></el-input>
            </div>
      
            <el-button @click="cancel">取 消</el-button>
            <el-button
              type="primary"
              @click="addBook"
            >确 定
            </el-button>
          </el-dialog>
        </div>
      </template>
      
      <script>
      // import { addbook } from '@/http/apis'
      export default {
        props: ['data', 'visible'],
        data() {
          return {}
        },
        methods: {
          addBook() {
            //$emit(update: prop, "newPropVulue")  这个模式,使子组件向父组件传达:更新属性,并抛出新的属性值
            this.$emit('update:visible', false)  // 隐藏弹出框
            this.$emit('save')
          },
          cancel() {
            this.$emit('update:visible', false)
          }
        },
        mounted() {
        }
      }
      </script>
      
      <style>
      .elinput {
         220px;
        height: 40px;
      }
      </style>
      
原文地址:https://www.cnblogs.com/wyx-zy/p/14032071.html