保姆级教程:Vue3 + Django + MySQL 前后端联调(PyCharm+VSCode版)

一、环境准备与验证

这里为减少篇幅,默认大家都安装好了这些软件。不会下载安装的,教程也很多,这里不再做赘述。话不多说,咱们开始:

1. 安装验证

确保已安装以下软件并验证版本:

python 复制代码
# 验证Node.js
node -v  # 应显示v16.x或更高,我安装的是v20.18.0
npm -v

# 验证Python
python --version  # 应显示3.8.x或更高,这是 Django 5.0 支持的最低版本。我用的3.12.9
pip --version

# 验证MySQL
mysql --version

2. 开发工具准备

  • PyCharm专业版:用于Django后端开发
  • VSCode:用于Vue前端开发
  • Navicat(可选):数据库可视化工具

二、MySQL数据库配置

如果有数据库可视化工具就直接点点点创建即可,这里不做赘述,只说明如何用命令行创建:

复制代码
mysql -u root -p //登录数据库,回车后输入密码即可

CREATE DATABASE fullstack;  //创建数据库,注意分号结尾

SHOW DATABASES; //产看数据库是否创建成功

示例:

注意,这里不用手动创建数据表或者使用原生SQL语句,下面在Django 中定义模型类并通过迁移系统创建表。这就是我们常说的ORM(对象关系映射)

三、后端项目初始化(PyCharm)

这里有两种方法,专业版的可以直接手动创建,不是专业版的可以用另一种命令行创建的方法。

  • 这里推荐大家学习使用如何用命令行创建,能够学到关于虚拟环境的创建方法。虚拟环境对于我们日后的学习如何管理python项目很有用。
  • 在虚拟环境中安装的库不会影响全局 Python 环境和其他虚拟环境。这样就可以为每个项目精确地安装所需的依赖,避免了不同项目之间依赖库版本的冲突。
  • 而且可以通过导出虚拟环境中的依赖列表(使用 pip freeze > requirements.txt 命令),来快速重建相同的环境

1. 创建Django项目

手动创建:

  1. 打开PyCharm → New Project
  2. 选择"Django"项目类型
  3. 配置:
    • Location: your-path/backend
    • Python解释器:选择3.8+
    • 勾选"Create virtual environment"
    • Django版本:5.0.3
  4. 点击Create

命令行创建

首先创建一个虚拟环境,注意我这里使用 conda 创建虚拟环境。

python 复制代码
conda create -n django_env python=3.12.9  //创建虚拟环境

conda activate django_env //激活虚拟环境

pip install django==5.0.3 //安装必要库

mkdir fullstack-project //创建文件夹,存放前后端项目文件

cd fullstack-project //切换到文件夹

django-admin startproject backend  //命令行创建项目文件

python manage.py startapp Login  //创建登录应用

pip install django-cors-headers mysqlclient// 在该虚拟环境下安装必要依赖 

其中:

  • django-cors-headers:用于解决 Django 项目中的跨域问题,配置灵活,使用简单。
  • mysqlclient:用于 Python 连接 MySQL 数据库,性能优越,功能强大,是 Django 推荐的 MySQL 数据库驱动之一。

用PyCharm打开即可看到目录结构长这样:

2.配置项目

修改 backend/settings.py:

python 复制代码
INSTALLED_APPS = [
    ...
    'rest_framework',
    'corsheaders',
    'Login',
]

MIDDLEWARE = [
   
    'corsheaders.middleware.CorsMiddleware',#需注意与其他中间件顺序,这里放在最前面即可
      ...
]

# 允许所有域名跨域访问(开发环境使用,生产环境需要配置具体域名)
CORS_ORIGIN_ALLOW_ALL = True

# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'fullstack',  //要创建的数据库名,我用的是fullstack
        'USER': 'your_mysql_username',  //数据库用户名
        'PASSWORD': 'your_mysql_password',  //数据库密码
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

3.模型定义(Login/models.py)

也就是通过简答的代码创建数据表,简单解释下:

  1. 将数据库表映射为类:每个数据库表对应一个类(称为模型类)。
  2. 将表中的记录映射为对象:表中的每一行数据对应一个对象实例。
  3. 通过对象操作数据库:开发者可以通过操作对象来实现对数据库的增、删、改、查操作,而无需直接编写 SQL 语句。
python 复制代码
(Login/models.py)

from django.db import models

# Create your models here.
class User(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)

编写完后打开终端cd到当前目录下,我们要创建迁移文件并应用迁移,也就是让代码生效:

python 复制代码
# 创建迁移文件并应用迁移
python manage.py makemigrations
python manage.py migrate

示例:

如果这时候你安装有可视化数据库软件,打开刷新即可看到 :

4.创建视图 (Login/views.py)

python 复制代码
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User

class RegisterView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        if username and password:
            user = User.objects.create(username=username, password=password)
            return Response("User created successfully", status=status.HTTP_201_CREATED)
        else:
            return Response("Username and password are required", status=status.HTTP_400_BAD_REQUEST)

5.配置URL

注意:这里需要配置两处urls。除默认创建好的,还要在Login目录下手动创建一个urls.py文件,注意区分!具体配置如下:

python 复制代码
(backend/urls.py) 
from django.contrib import admin
from django.urls import path,include

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

(backend/Login/urls.py)
from django.urls import path
from .views import RegisterView

urlpatterns = [
    path('register/', RegisterView.as_view(), name='register'),
]

6.启动后端

在完成上面操作后,在终端当前目录下,运行以下命令,启动后端:

python 复制代码
python manage.py runserver

示例:

四、前端项目初始化(VSCode)

1.创建vue3项目

这里记得进入到目录fullstack-project下

进入目录后运行以下命令:注意这个命令是安装Node.js中之后才能运行的。这一指令将会安装并执行 create-vue,它是 Vue 官方的项目脚手架工具。你将会看到一些诸如 TypeScript 和测试支持之类的可选功能提示:

如果不知道怎么选的按我这个就行,然后回车应该还会有功能,不用再空格选了,直接回车。frontend创建好后进入该目录,然后按提示依次运行命令即可:

注意:npm run format 是一个用于代码格式化的命令,通常用于确保代码风格一致。它并不是启动项目的必要步骤。这里直接跳过,运行启动命令即可正常启动。

运行命令启动看是否创建成功,点击出现的默认url:

python 复制代码
npm run dev

示例:

2.配置项目

VS Code打开刚创建好的前端项目,这里还要做一些小配置,为前后端联调做准备。

Ctrl+` 打开终端 ,安装以下依赖项,其中,axios 用于与后端进行数据交互,vue-router 用于实现页面的路由管理

复制代码
npm install axios vue-router

安装好后还要手动修改一下目录结构:

复制代码
frontend/
├── src/
│   ├── api/            # API请求封装
│   ├── router/         # 路由配置
│   ├── views/          # 页面组件
│   ├── App.vue
│   └── main.ts

然后将main.ts中的第一行样式注销:这是为了防止默认样式干扰操作。

配置代理 (解决跨域)

在 **frontend/vite.config.js**中添加:

javascript 复制代码
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true,
      }
    }
  }
  
})

3.创建注册页面

这里为方便直接在App.vue文件中作修改。拿去复制即可:

javascript 复制代码
<template>

  <div class="container">
    <div class="box">
      <div class="header">
        <h2>欢迎注册</h2>

         <svg t="1743150356672" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
          p-id="4191" width="48" height="48">
          <path
            d="M767.818667 409.173333C867.338667 444.266667 938.666667 539.136 938.666667 650.666667c0 42.709333-10.496 83.978667-30.261334 120.842666-1.792 3.338667-4.992 8.928-9.696 16.96l14.613334 53.557334c6.506667 23.893333-15.402667 45.813333-39.296 39.296l-53.642667-14.634667-6.229333 3.669333A254.933333 254.933333 0 0 1 682.666667 906.666667c-77.994667 0-147.84-34.88-194.805334-89.888a352.608 352.608 0 0 1-56.64 4.554666c-63.338667 0-124.266667-16.853333-177.472-48.298666-1.834667-1.088-6.410667-3.733333-13.632-7.893334l-80.544 21.653334c-23.914667 6.432-45.76-15.573333-39.146666-39.434667l21.792-78.752a961.205333 961.205333 0 0 1-15.904-27.317333A336.384 336.384 0 0 1 85.333333 480c0-188.618667 154.965333-341.333333 345.888-341.333333 159.914667 0 297.984 108.010667 335.818667 259.296 0.949333 3.765333 1.173333 7.552 0.778667 11.2z m-68.106667-13.952C662.88 282.037333 555.178667 202.666667 431.221333 202.666667 275.434667 202.666667 149.333333 326.933333 149.333333 480c0 46.272 11.498667 90.837333 33.194667 130.698667 2.88 5.290667 10.176 17.706667 21.621333 36.746666a32 32 0 0 1 3.413334 25.013334l-10.517334 37.994666 39.232-10.549333a32 32 0 0 1 24.234667 3.146667c14.272 8.192 22.773333 13.098667 25.802667 14.890666A283.882667 283.882667 0 0 0 431.221333 757.333333c6.154667 0 12.288-0.192 18.389334-0.576A255.061333 255.061333 0 0 1 426.666667 650.666667c0-141.386667 114.613333-256 256-256 5.728 0 11.413333 0.192 17.045333 0.554666z m133.706667 397.056a32 32 0 0 1 3.338666-24.725333 996.672 996.672 0 0 0 15.242667-26.293333A190.997333 190.997333 0 0 0 874.666667 650.666667c0-106.037333-85.962667-192-192-192s-192 85.962667-192 192 85.962667 192 192 192a190.933333 190.933333 0 0 0 98.570666-27.2c2.208-1.322667 8.288-4.874667 18.517334-10.837334a32 32 0 0 1 24.522666-3.210666l12.565334 3.424-3.424-12.565334zM330.666667 426.666667a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z m192 0a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z m85.333333 202.666666a32 32 0 1 1 0-64 32 32 0 0 1 0 64z m149.333333 0a32 32 0 1 1 0-64 32 32 0 0 1 0 64z"
            fill="#000000" p-id="4192"></path>
        </svg>
      </div>
      <div class="content">
        <form @submit.prevent="login">
          <div class="form-item">
            <label>用户名:</label>
            <input v-model="username" type="text" required placeholder="请输入用户名">

          </div>
          <div class="form-item">
            <label>密码:</label>
            <input v-model="password" type="password" required placeholder="请输入密码">

          </div>
          <div class="button-group">
            <button class="register-btn">注册</button>
          </div>
        </form>

      </div>

    </div>
  </div>
  <!-- <RouterView /> -->
</template>
<script setup lang="ts">
import axios from 'axios'
import { ref } from 'vue'
const username = ref('')
const password = ref('')


const login = async () => {
  try {
    const response = await axios.post('http://localhost:8000/Login/register/', {
      username: username.value,
      password: password.value
    })
    console.log(response)

    alert(response.data)

  } catch (error: any) {
    console.log(error.response)
  }

}


</script>
<style scoped>
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  /* 使用视口高度,确保容器高度覆盖整个屏幕 */

  .box {
    width: 400px;
    height: 400px;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);

    .header {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-top: 10px;

      h2 {
        margin-left: 10px;

      }
    }

    .form-item {
      /* display: flex; */
      flex-direction: column;

      margin: 20px 0;

      label {
        display: block;
        margin-bottom: 8px;
        color: #666;
        margin-left: 50px;
      }

      input {
        width: 300px;
        height: 30px;
        border: 1px solid #ccc;
        border-radius: 5px;
        margin-left: 50px;

      }
    }

    .content {
      .form-item1 {
        display: flex;
        align-items: center;


        label {

          margin-bottom: 8px;
          color: #666;
          margin-left: 30px;
        }

        input {

          width: 300px;
          height: 30px;
          border: 1px solid #ccc;
          border-radius: 5px;
        }


      }

      .button-group {
        display: flex;
        justify-content: center;
        margin-top: 30px;


        .register-btn {
          background-color: #67C23A;
          color: white;
          width: 200px;
          height: 40px;
          border-radius: 4px;
          border: none;
          /* 去掉边框 */
          cursor: pointer;
          /* 鼠标移上去显示手型 */
          font-size: 16px;
          transition: background-color 0.3s;
          /*平滑过渡:当元素的背景颜色发生变化时,不会立即切换,而是会在0.3秒内逐渐过渡到新的颜色。*/
        }

        .register-btn:hover {
          background-color: #85ce61;
        }
      }
    }
  }
}
</style>

样式:

在 Vue 3 中,const login = async () => { ... } 是一种常用的定义异步函数的方法,但它并不是 Vue 3 特有的写法,而是 JavaScript 的语法。这种写法在 Vue 3 的代码中非常常见,尤其是在处理异步逻辑(如 API 请求)时。

这时候试着输入内容,点击注册,即可看到弹框内容:注册成功。

查看数据库看到,内容成功存入数据库:

总结

顺利走到这就实现了一个简单的前后端联调注册功能^-^

相关推荐
mygljx17 小时前
MySQL 数据库连接池爆满问题排查与解决
android·数据库·mysql
终端鹿18 小时前
Vue2 迁移 Vue3 避坑指南
前端·javascript·vue.js
Bdygsl18 小时前
MySQL(1)—— 基本概念和操作
数据库·mysql
身如柳絮随风扬18 小时前
什么是左匹配规则?
数据库·sql·mysql
liurunlin88818 小时前
Go环境搭建(vscode调试)
开发语言·vscode·golang
jiankeljx18 小时前
mysql之如何获知版本
数据库·mysql
SuperEugene19 小时前
TypeScript+Vue 实战:告别 any 滥用,统一接口 / Props / 表单类型,实现类型安全|编码语法规范篇
开发语言·前端·javascript·vue.js·安全·typescript
chushiyunen19 小时前
pycharm注意力残差示例
ide·python·pycharm
B站_计算机毕业设计之家19 小时前
计算机毕业设计:Python当当网图书数据全链路处理平台 Django框架 爬虫 Pandas 可视化 大数据 大模型 书籍(建议收藏)✅
爬虫·python·机器学习·django·flask·pandas·课程设计
小李来了!19 小时前
数据库DDL、DML、DQL、DCL详解
数据库·mysql