Vue+Django前后端实例1

2022年7月17日09:17:51

后端:

python manage.py startapp block 创建APP,并在settings的INSATLLED_APP中添加'block'。

block目录下创建models.py

from django.db import models

# Create your models here.
# models.py

class Blog(models.Model):
    title = models.CharField(max_length=50)
    content = models.CharField(max_length=500)

    # 自定义表名
    class Meta:
        db_table = "t_blog"

与数据库连接

python manage.py makemigrations

python manage.py migeate

终端打开python manage.py shell

手动添加数据

from block.models import Blog

Blog.objects.create("title="b1", content="b1 content")

Blog.objects.create("title="b1", content="b1 content")

查询目前添加的数据 Blog.objects.all()

退出exit()

使用rest_framework, pip install djangorestframework安装包

settings的INSATLLED_APP中添加'rest_framework'

block目录下创建serializers.py

#serializers.py
from rest_framework import serializers
from .models import Blog


class BlogSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Blog  # 序列化的对象名
        fields = '__all__'  # 序列化的字段名,或者指定字段 fields = ("id","name","age")

block目录下创建views.py

#views.py
from rest_framework import viewsets
from .models import Blog
from .serializers import BlogSerializer


class BlogViewSet(viewsets.ModelViewSet):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

配置路由

crude目录下urls.py文件

#urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from block.views import BlogViewSet

router = routers.DefaultRouter()
router.register('blog', BlogViewSet)

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

解决跨域问题

pip install django-cors-headers

在settings.py中做如下修改

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'block',
]
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
CORS_ALLOW_CREDENTIALS = True

最后文件构成为

前端

vue init webpack crude创建vue项目

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link  href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link  href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <title>crude</title>
  </head>
  <body>
    <div class="container">
      <nav class="navbar" navbar-dark bg-success>
        <a class="navbar-brand">博客系统</a>
        <form class="form-inline">
          <input class="form-control" mr-sm-2 type="search" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
      </nav>
      <div id="app"></div>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

APP.vue

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

src/components/Container.vue

<template>
  <div class="row">
    <!--左右两屏-->
    <div class="col-md-4">
      <!--左边是编辑部分-->
      <div class="form-group">
        <input type="hidden" v-model="url">
      </div>
      <div class="form-group">
        <input type="text" v-model="title"  class="form-control" placeholder="标题"> 
      </div>
      <div class="form-group">
        <textarea class="form-control" v-model="content" placeholder="内容"></textarea>
      </div>
      <div class="form-group">
        <button class="btn btn-block btn-success" @click="saveBlog()">保存</button>
      </div>
      <div class="form-group">
        
      </div>
    </div> 
    <div class="col-md-8">
      <!--右边是博客内容表格部分-->
      <table class="table table-bordered table-hover">
        <thead>
          <th class="text-center">标题</th>
          <th class="text-center">内容</th>
          <th class="text-center">编辑</th>
          <th class="text-center">删除</th>
        </thead>
        <tbody>
          <tr v-for="blog in blogs" :key="blog.url">
            <td>{{blog.title}}</td>
            <td>{{blog.content}}</td>
            <td>
              <button class="btn btn-success"  @click="editBlog(blog)">
                <i class="fa fa-edit"></i>
              </button>
            </td>
            <td>
              <button class="btn btn-success"  @click="deleteBlog(blog)">
                <i class="fa fa-trash"></i>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
 
<script>
//添加axios.http请求组件
import axios from 'axios'
export default {
  name: 'Container',
  props:{

  },
  data(){
    return{
      base_url:"http://127.0.0.1:8000/api/blog/",
      blogs:null,
      url:"",
      title:"",
      content:"",
    }
  },
  methods:{
    getAll(){
        axios.get(this.base_url)
        .then(res=>{
            this.blogs = res.data;  //获取列表数据
            this.url="";
            this.title="";
            this.content="";
        }); 
    },
    saveBlog(){
        //新增
        if(this.url==""){
            axios.post(this.base_url,{title:this.title, content:this.content})
            .then(()=>{
                this.getAll();
            })
        }
        //修改
        else{
            axios.put(this.url,{title:this.title, content:this.content})
            .then(()=>{
                this.getAll();
            })
        }
    },
    editBlog(blog){
        this.url= blog.url;
        this.title=blog.title;
        this.content=blog.content;
    },
    deleteBlog(blog){
        axios.delete(blog.url)
        .then(()=>{
            this.getAll();
        });
    },
  },
  mounted(){
      this.getAll();
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

router/index.js

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

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Container',
      component: Container
    }
  ]
})
  • 作者:Scarlett1007
  • 原文链接:https://blog.csdn.net/weixin_59057086/article/details/122750889
    更新时间:2022年7月17日09:17:51 ,共 5816 字。