django与vue的完美结合_实现前后端的分离开发之后在整合的方法

下面将为你详细讲解“Django与Vue的完美结合——实现前后端的分离开发之后在整合的方法”。

1.前言

Django和Vue都是非常流行的Web开发框架,Django是一款开源的Python Web框架,Vue是一款渐进式JavaScript框架,常用于构建单页面应用(SPA)。在Web开发中,前端与后端的分离已经成为了主流趋势,而Django和Vue的完美结合,就是基于前后端分离的开发方式实现的。

2.前后端分离开发示例

通过一个实例来介绍前后端分离开发并实现前后端分离的方式。

2.1前端开发

1.安装Vue

npm install vue --save

2.新建Vue项目

vue init webpack frontend

3.在Vue项目中使用Axios请求后端接口

import axios from 'axios'

const BASE_URL = '/api/'

export function getUsers() {
  return axios.get(`${BASE_URL}users/`)
}

export function getUser(id) {
  return axios.get(`${BASE_URL}users/${id}/`)
}

2.2后端开发

1.安装Django

pip install django

2.新建Django项目

django-admin startproject backend

3.新建Django应用

cd backend/
python manage.py startapp users

4.编写Django视图

from django.http import JsonResponse
from django.shortcuts import get_object_or_404

from .models import User

def get_users(request):
    users = User.objects.all()
    data = [{'id': user.id, 'name': user.name, 'email': user.email} for user in users]
    return JsonResponse(data, safe=False)

def get_user(request, user_id):
    user = get_object_or_404(User, id=user_id)
    data = {'id': user.id, 'name': user.name, 'email': user.email}
    return JsonResponse(data, safe=False)

2.3前后端分离后的优势

前端与后端的分离开发方式有如下优势:

1.提高开发效率,各自开发负责自己的领域,降低了开发人员之间的耦合程度。

2.前端可以选择合适的框架进行开发,可以选择好用的UI组件库进行开发,提高了前端的体验。

3.后端与前端的数据交互更加清晰明了。

3.整合前后端示例

借助Webpack将前端资源打包,然后将打包后的资源嵌入Django模板中,在templates文件夹下新建一个index.html文件,可以像下面这样嵌入Webpack打包后的JavaScript和CSS文件:

{% load static %}

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Vue-Django Demo</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.13.1/css/all.min.css" rel="stylesheet">
    <link href="{% static 'css/app.39428fbe.css' %}" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div>
    <script src="{% static 'js/manifest.4099bc10.js' %}"></script>
    <script src="{% static 'js/vendor.e1d11a23.js' %}"></script>
    <script src="{% static 'js/app.3db97568.js' %}"></script>
  </body>
</html>

其中{% static %}是Django模板标签,用于获取静态文件的路径,静态文件可以放在static文件夹中。

4.整合前后端完整代码

下面是整合前后端的示例代码:

4.1前端代码

// frontend/src/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

import '@/assets/css/base.css'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

// frontend/src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home.vue'
import Users from '@/views/Users.vue'
import UserDetail from '@/views/UserDetail.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/users',
    name: 'users',
    component: Users
  },
  {
    path: '/user/:id',
    name: 'user-detail',
    component: UserDetail
  }
]

const router = new VueRouter({
  routes
})

export default router

// frontend/src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import { getUsers, getUser } from '@/api/users'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    users: [],
    currentUser: null
  },
  getters: {
    users: state => state.users,
    currentUser: state => state.currentUser
  },
  mutations: {
    setUsers(state, users) {
      state.users = users
    },
    setCurrentUser(state, user) {
      state.currentUser = user
    }
  },
  actions: {
    async getUsers({ commit }) {
      const response = await getUsers()
      const users = response.data
      commit('setUsers', users)
    },
    async getUser({ commit }, id) {
      const response = await getUser(id)
      const user = response.data
      commit('setCurrentUser', user)
    }
  }
})

// frontend/src/api/users.js

import axios from 'axios'

const BASE_URL = '/api/'

export function getUsers() {
  return axios.get(`${BASE_URL}users/`)
}

export function getUser(id) {
  return axios.get(`${BASE_URL}users/${id}/`)
}

// frontend/src/components/UserList.vue

<template>
  <div>
    <h2>用户列表</h2>
    <ul class="list-group">
      <li v-for="user in users" :key="user.id" class="list-group-item">
        <router-link :to="{ name: 'user-detail', params: { id: user.id } }">{{ user.name }}</router-link>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'UserList',
  computed: {
    ...mapGetters(['users'])
  },
  created() {
    this.$store.dispatch('getUsers')
  }
}
</script>

// frontend/src/components/UserDetail.vue

<template>
  <div>
    <h2>{{ user.name }}</h2>
    <p>{{ user.email }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'UserDetail',
  computed: {
    ...mapGetters(['currentUser']),
    user() {
      return this.currentUser ? this.currentUser : {}
    }
  },
  created() {
    this.getUser()
  },
  methods: {
    getUser() {
      const id = this.$route.params.id
      this.$store.dispatch('getUser', id)
    }
  }
}
</script>

// frontend/src/views/Users.vue

<template>
  <div>
    <UserList />
  </div>
</template>

<script>
import UserList from '@/components/UserList.vue'

export default {
  name: 'Users',
  components: {
    UserList
  }
}
</script>

// frontend/src/views/Home.vue

<template>
  <div class="home">
    <h1>VUE - DJANGO DEMO</h1>
    <p>这是一个使用Vue和Django实现的Web应用程序。代码已经托管在Github上,欢迎您的传送。</p>
    <p><a href="https://github.com/Kevin-07/vue-django-demo/">查看 Github 代码</a></p>
  </div>
</template>

<style>
.home {
  margin-top: 50px;
  text-align: center;
}
</style>

// frontend/src/App.vue

<template>
  <div id="app">
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <router-link class="navbar-brand" to="/">Vue-Django Demo</router-link>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item">
            <router-link class="nav-link" to="/">首页</router-link>
          </li>
          <li class="nav-item">
            <router-link class="nav-link" to="/users">用户列表</router-link>
          </li>
        </ul>
      </div>
    </nav>
    <div class="container mt-3">
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style>
/* Put your own stylesheet here */
</style>

// frontend/src/assets/css/base.css

body {
  margin: 0;
  padding: 0;
}

ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}

a {
  color: black;
  text-decoration: none;
}

a:hover {
  color: black;
  text-decoration: none;
}

.list-group-item {
  cursor: pointer;
}

4.2后端代码

# backend/backend/settings.py

INSTALLED_APPS = [
    'users.apps.UsersConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

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

ROOT_URLCONF = 'backend.urls'

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',
            ],
        },
    },
]

WSGI_APPLICATION = 'backend.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True

static_url = '/static/'
MEDIA_URL = '/media/'

STATICFILES_DIRS = [
    BASE_DIR / 'frontend' / 'dist' / 'static',
]

STATIC_ROOT = BASE_DIR / 'static'
MEDIA_ROOT = BASE_DIR / 'media'

# backend/backend/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from django.views.generic import TemplateView

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

api_patterns = ([
    path('users/', include('users.urls')),
])

urlpatterns += api_patterns

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

urlpatterns += [
    path('', TemplateView.as_view(template_name='index.html')),
]

# backend/users/models.py

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __str__(self):
        return self.name

# backend/users/views.py

from django.http import JsonResponse
from django.shortcuts import get_object_or_404

from .models import User

def get_users(request):
    users = User.objects.all()
    data = [{'id': user.id, 'name': user.name, 'email': user.email} for user in users]
    return JsonResponse(data, safe=False)

def get_user(request, user_id):
    user = get_object_or_404(User, id=user_id)
    data = {'id': user.id, 'name': user.name, 'email': user.email}
    return JsonResponse(data, safe=False)

# backend/users/urls.py

from django.urls import path

from .views import get_users, get_user

urlpatterns = [
    path('users/', get_users),
    path('users/<int:user_id>/', get_user),
]

# backend/users/admin.py

from django.contrib import admin

from .models import User

class UserAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'email']

admin.site.register(User, UserAdmin)

# backend/users/apps.py

from django.apps import AppConfig

class UsersConfig(AppConfig):
    name = 'users'

5.总结

通过上述示例可知,Django与Vue的完美结合,在前后端分离的基础上,结合Webpack将前端资源打包,然后将打包后的资源嵌入Django模板中,可以实现前后端的无缝衔接。在开发过程中,可以对前端和后端分别进行优化和管理,提高开发效率。同时,前后端分离的方式还可以实现前后端的部署与维护分离,对于复杂的应用程序具有较好的可维护性和扩展性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django与vue的完美结合_实现前后端的分离开发之后在整合的方法 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • Django之DRF操作(细节干货)

    DRF操作全部干货,细节满满。 目录 1.DRF初始化 1.1安装DjangoRestFramework 1.2在syl/settings.py中注册 1.3 在settings.py中配置 1.4创建user/serializer.py写序列化器 2.DRF认证、权限、限流、分页、过滤、序列化 2.2 编写user/views.py 1.DRF初始化 DR…

    Django 2023年4月10日
    00
  • 浅谈django model的get和filter方法的区别(必看篇)

    当我们使用Django进行开发时,经常会使用到Model的get和filter方法。两者都可以用来查询数据库中符合条件的数据,但是它们之间究竟有什么区别呢?下面对这个问题进行详细讲解。 一、Django中Model的get方法 get方法用于查询唯一的一条记录,它的使用方法如下: class ModelName(models.Model): field1 =…

    Django 2023年5月15日
    00
  • Django视图层

    目录 Django视图层 一、视图层之必会三板斧 二、JsonResponse对象 三、request对象 四、视图层之FBV与CBV 五、CBV源码剖析 六、虚拟环境 Django视图层 一、视图层之必会三板斧 用来处理请求的视图函数都必须返回HttpResponse对象 # 完全正确 class HttpResponse: pass return Htt…

    Django 2023年4月10日
    00
  • Django框架(十九)–Django rest_framework-认证组件

    一、什么是认证 只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 二、利用token记录认证过的用户 1、什么是token token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上…

    Django 2023年4月16日
    00
  • Django设置/获取/删除session

    # 设置sessiondef setSession(request): request.session[‘username’] = ‘ruan’ request.session[‘isLogin’] = True return HttpResponse(‘OK’)# 获取session def GetSession(request): isLogin = r…

    Django 2023年4月13日
    00
  • django中资源文件夹的引入及配置方法

    Sure!以下是详细讲解django中资源文件夹的引入及配置方法的完整攻略: 1. 关于Django资源文件夹 Django的资源文件夹主要包括static和media两个文件夹,它们分别用于存储静态文件和媒体文件。这些文件可以被引用到项目的模板和视图中,用于呈现图像、CSS样式、JavaScript文件等。在编写Django应用程序时,我们需要了解它们的引…

    Django 2023年5月16日
    00
  • Django发送邮件,注册时邮件获取验证码

    settings.py里面的配置 1 # 邮件 2 EMAIL_HOST = ‘smtp.163.com’ 3 # 设置端口号,为数字 4 EMAIL_PORT = 25 5 #设置发件人邮箱 6 EMAIL_HOST_USER = ‘kongfuzi_k@163.com’ 7 # 设置发件人 授权码 8 EMAIL_HOST_PASSWORD = ‘123…

    Django 2023年4月13日
    00
  • DJANGO复制记录的方法(转载)

    DJANGO复制记录的方法 https://dmyz.org/archives/326 最近的Django项目中有复制记录的需求。数据库里有一张名为Party的表,记录用户创建的party,现在要让用户能够复制一个新的party。本身非常简单的一个功能,但运行的时候出错了。我以为是复制过程出错,所以测试了一下Django中复制记录可能遇到的情况(后来发现是其…

    Django 2023年4月12日
    00
合作推广
合作推广
分享本页
返回顶部