1.前后端分离的架构
在前后端分离的架构中,前端和后端分别作为独立的项目举行开辟和摆设。前端项目通过API与后端项目举行通信。
- 前端:使用Vue.js构建用户界面,调用后端提供的RESTful API获取和发送数据。
- 后端:使用Django构建API,处理业务逻辑和数据存储
2.创建django项目及vue项目
创建app的时候必要进入项目的目录下 win10 cd xmmc
- django-admin startproject xmmc
- django-admin startapp app01
复制代码 以管理员身份打开命令行界面,进入恣意一个想要创建项目的文件夹
然后按自己的需求选择,可以去专门搜一下创建vue的教程
3.设置setting
(1)设置数据库
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql', # 加载mysql引擎
- 'NAME': 'db_goods', # 数据库名称
- 'USER': 'root', # mysql账户名
- 'PASSWORD': '123456', # mysql账户密码
- 'PORT': 3306, # 端口号
- 'HOST': 'localhost'
- }
- }
复制代码 (2)设置模板文件
- TEMPLATES = [
- {
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [os.path.join(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',
- ],
- },
- },
- ]
复制代码 (3)设置静态文件
- STATIC_URL = 'static/'
- STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
复制代码 (4)注册app(使用创建 django-admin startapp app名称)
(5)解决跨域问题
- 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
- # 允许所有的请求头
- CORS_ALLOW_HEADERS = ('*')
复制代码 4.查看目录结构
- web_django/
- ├── static/
- ├── templates/
- ├── user/
- │ ├── migrations/
- │ ├── __init__.py
- │ ├── admin.py
- │ ├── apps.py
- │ ├── models.py
- │ ├── tests.py
- │ ├── urls.py
- │ ├── views.py
- ├── web_django/
- │ ├── __init__.py
- │ ├── asgi.py
- │ ├── settings.py
- │ ├── urls.py
- │ ├── wsgi.py
- ├── webapp/
- │ ├── migrations/
- │ ├── views/
- │ ├── __init__.py
- │ ├── admin.py
- │ ├── apps.py
- │ ├── models.py
- │ ├── tests.py
- │ ├── urls.py
- │ ├── views.py
复制代码 5.前后端实现登录
(1)编写登录的前端(完备代码)
- <template>
- <div class="login-background">
- <div class="login-container">
- <el-card class="box-card" style="opacity: 0.9;">
- <h2>登录</h2>
- <el-form
- :model="ruleForm"
- status-icon
- :rules="rules"
- ref="ruleForm"
- label-position="left"
- label-width="70px"
- class="login-form"
- >
- <el-form-item label="用户名" prop="uname">
- <el-input v-model="ruleForm.uname"></el-input>
- </el-form-item>
- <el-form-item label="密码" prop="password">
- <el-input
- type="password"
- v-model="ruleForm.password"
- autocomplete="off"
- ></el-input>
- </el-form-item>
- </el-form>
- <div class="btn-group">
- <el-button type="primary" @click="submitForm('ruleForm')"
- >登录</el-button
- >
- <el-button @click="resetForm('ruleForm')">重置</el-button>
- <router-link to="/register">
- <el-button style="margin-left:10px">注册</el-button>
- </router-link>
- </div>
- </el-card>
- </div>
- </div>
- </template>
- <script>
- import axios from 'axios';
- export default {
- data() {
- return {
- ruleForm: {
- uname: "",
- password: "",
- },
- rules: {
- uname: [
- { required: true, message: "用户名不能为空!", trigger: "blur" },
- ],
- password: [
- { required: true, message: "密码不能为空!", trigger: "blur" },
- ],
- },
- };
- },
- methods: {
- async submitForm(formName) {
- try {
- const response = await axios.post('http://127.0.0.1:8005/user/login/', this.ruleForm);
- // 在这里处理后端响应
- console.log(response.data);
- if (response.data.success) {
- sessionStorage.setItem('username', JSON.stringify(response.data))
- // 登录成功,跳转到 Index 页面
- this.$router.push('/components/News');
- } else {
- // 登录失败,显示错误消息或其他处理
- console.error('登录失败:', response.data.message);
- }
- } catch (error) {
- console.error('提交表单时发生错误:', error);
- }
- },
- resetForm(formName) {
- this.$refs[formName].resetFields();
- },
- },
- };
- </script>
- <style scoped>
- .login-background {
- background-image: url('https://pic4.zhimg.com/v2-b730c73ebd78bd5f22293aab0d343f4b_r.jpg?source=1940ef5c');
- background-size: cover;
- background-position: center;
- height: 100vh;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .box-card {
- width: 400px;
- }
- .login-form {
- margin: auto;
- }
- .btn-group {
- margin-top: 20px;
- }
- </style>
复制代码 登录效果图
(2)编写登录后端views(视图文件)
- from django.http import JsonResponse
- from django.contrib.auth import authenticate, login
- from django.contrib.auth.models import User
- import json
- def login_view(request):
- # if request.method == 'GET':
- if request.method == 'POST':
- js = request.body.decode('utf8')
- data = json.loads(js)
- username = data['uname']
- password = data['password']
- # 使用 Django 自带的 authenticate 方法验证用户身份
- user = authenticate(request, username=username, password=password)
- if user is not None:
- # 登录成功,将用户添加到当前会话中
- login(request, user)
- print(user)
- return JsonResponse({'code': 200, 'success': True, 'message': '登录成功', 'username': str(user)})
- else:
- # 登录失败,返回错误消息
- return JsonResponse({'code': 500, 'success': False, 'message': '用户名或密码错误', })
- # 如果不是 POST 请求,则返回错误消息
- return JsonResponse({'success': False, 'message': '只支持 POST 请求'})
- def register_view(request):
- if request.method == 'POST':
- # 从请求体中获取JSON数据
- js = request.body.decode('utf8')
- data = json.loads(js)
- print(data)
- username = data['uname']
- password = data['password']
- # 检查用户名是否已经存在
- if User.objects.filter(username=username).exists():
- return JsonResponse({'code': 400, 'success': False, 'message': '用户名已存在'})
- # 创建用户
- user = User.objects.create_user(username=username, password=password)
- # 返回成功消息
- return JsonResponse({'code': 200, 'success': True, 'message': '注册成功', 'username': username})
- # 如果不是 POST 请求,则返回错误消息
- return JsonResponse({'code': 405, 'success': False, 'message': '只支持 POST 请求'})
复制代码 (3)子视图文件(在user app中创建一个urls)
- from . import views
- from django.urls import path, re_path
- urlpatterns = [
- path('login/', views.login_view, name='login'),
- path('register/', views.register_view, name='register'),
- ]
复制代码 (4)在主路由中设置user app(主路由跟setting在同一个文件夹)
6.管理页面的前后端完备代码
(1)管理页面前端代码(业务范围页面)
- <template>
- <div>
- <el-row style="height: 50px;">
- <el-col :span="1" class="grid">
- <el-button
- type="success"
- @click="showAddDialog"
- icon="el-icon-circle-plus-outline"
- size="mini"
- round
- >新增</el-button>
- </el-col>
- </el-row>
- <el-dialog title="新增" :visible.sync="addDialogVisible" width="42%">
- <el-form :model="addFormData" :rules="addFormRules" ref="addForm" label-width="120px">
- <el-form-item label="标题" prop="title">
- <el-input v-model="addFormData.title"></el-input>
- </el-form-item>
- <el-form-item label="图片链接" prop="image_url">
- <el-input v-model="addFormData.image_url"></el-input>
- </el-form-item>
- <el-form-item label="内容" prop="content">
- <el-input v-model="addFormData.content"></el-input>
- </el-form-item>
- <el-form-item label="图片详情链接" prop="details_image_url">
- <el-input v-model="addFormData.details_image_url"></el-input>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button @click="addDialogVisible = false">取 消</el-button>
- <el-button type="primary" @click="submitAddForm">确 定</el-button>
- </span>
- </el-dialog>
- <el-dialog title="编辑" :visible.sync="editDialogVisible" width="40%">
- <el-form :model="editFormData" :rules="editFormRules" ref="editForm" label-width="100px">
- <el-form-item label="标题" prop="title">
- <el-input v-model="editFormData.title"></el-input>
- </el-form-item>
- <el-form-item label="图片链接" prop="image_url">
- <el-input v-model="editFormData.image_url"></el-input>
- </el-form-item>
- <el-form-item label="内容" prop="content">
- <el-input v-model="editFormData.content"></el-input>
- </el-form-item>
- <el-form-item label="图片详情链接" prop="details_image_url">
- <el-input v-model="editFormData.details_image_url"></el-input>
- </el-form-item>
- </el-form>
- <span slot="footer" class="dialog-footer">
- <el-button @click="editDialogVisible = false">取 消</el-button>
- <el-button type="primary" @click="submitEditForm">确 定</el-button>
- </span>
- </el-dialog>
- <el-table
- :data="tableData.slice((currentPage-1)*pagesize,currentPage*pagesize)"
- style="width: 100%; margin-top: 10px;"
- border
- stripe
- ref="multipleTable"
- tooltip-effect="dark"
- >
- <el-table-column label="序号" type="index" width="80px" align="center"></el-table-column>
- <el-table-column prop="title" width="100px" label="标题"></el-table-column>
- <el-table-column prop="image_url" width="150px" label="图片链接"></el-table-column>
- <el-table-column prop="content" width="120px" label="内容"></el-table-column>
- <el-table-column prop="details_image_url" label="图片详情链接"></el-table-column>
- <el-table-column width="190px" label="操作">
- <template slot-scope="scope">
- <el-button type="primary" icon="el-icon-edit" size="mini" @click="editBook(scope.row)">编辑</el-button>
- <el-button
- icon="el-icon-delete"
- size="mini"
- type="danger"
- @click="confirmDelete(scope.row)"
- >删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <div class="pagination">
- <el-pagination
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="currentPage"
- :page-sizes="[5, 10, 20, 40]"
- :page-size="pagesize"
- layout="total, sizes,prev, pager, next"
- :total="tableData.length"
- prev-text="上一页"
- next-text="下一页"
- ></el-pagination>
- </div>
- </div>
- </template>
- <script>
- import axios from "axios";
- import { MessageBox } from "element-ui";
- export default {
- name: "app",
- data() {
- return {
- currentPage: 1, // 默认显示页面为1
- pagesize: 5, // 每页的数据条数
- tableData: [], // 需要 data 定义一些,tableData 定义一个空数组,请求的数据都是存放这里面
- addDialogVisible: false,
- activeIndex2: "1",
- addFormData: {
- title: "",
- image_url: "",
- content: "",
- details_image_url: ""
- },
- addFormRules: {
- title: [{ required: true, message: "请输入标题", trigger: "blur" }],
- image_url: [
- { required: true, message: "请输入图片地址", trigger: "blur" }
- ],
- content: [{ required: true, message: "请输入内容", trigger: "blur" }],
- details_image_url: [
- { required: true, message: "请输入图片详情", trigger: "blur" }
- ]
- },
- editDialogVisible: false,
- editFormData: {
- id: null,
- title: "",
- image_url: "",
- content: "",
- details_image_url: ""
- },
- editFormRules: {
- title: [{ required: true, message: "请输入标题", trigger: "blur" }],
- image_url: [
- { required: true, message: "请输入图片地址", trigger: "blur" }
- ],
- content: [{ required: true, message: "请输入内容", trigger: "blur" }],
- details_image_url: [
- { required: true, message: "请输入图片详情", trigger: "blur" }
- ]
- }
- };
- },
- mounted() {
- this.getData();
- },
- methods: {
- getData() {
- axios.get(" http://127.0.0.1:8005/web_drf/coreBusinessView/").then(
- response => {
- console.log(response.data);
- this.tableData = response.data;
- },
- error => {
- console.log("error");
- }
- );
- },
- handleSizeChange(size) {
- this.pagesize = size;
- },
- handleCurrentChange(currentPage) {
- this.currentPage = currentPage;
- },
- showAddDialog() {
- this.addDialogVisible = true;
- },
- submitAddForm() {
- this.$refs.addForm.validate(valid => {
- if (valid) {
- axios
- .post(
- " http://127.0.0.1:8005/web_drf/coreBusinessView/",
- this.addFormData
- )
- .then(response => {
- console.log("新增成功", response.data);
- this.addDialogVisible = false;
- this.getData();
- this.addFormData = {
- title: "",
- image_url: "",
- content: "",
- details_image_url: ""
- };
- })
- .catch(error => {
- console.error("新增失败", error);
- });
- }
- });
- },
- confirmDelete(book) {
- MessageBox.confirm("确定删除该条记录吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- })
- .then(() => {
- this.deleteBook(book);
- })
- .catch(() => {
- // 取消删除操作
- });
- },
- deleteBook(book) {
- const url = ` http://127.0.0.1:8005/web_drf/coreBusinessView/${book.id}/`;
- console.log(book.id);
- axios
- .delete(url)
- .then(response => {
- console.log("删除成功");
- this.getData();
- })
- .catch(error => {
- console.error("删除失败", error);
- });
- },
- editBook(book) {
- this.editFormData = { ...book };
- this.editDialogVisible = true;
- },
- submitEditForm() {
- this.$refs.editForm.validate(valid => {
- if (valid) {
- const url = ` http://127.0.0.1:8005/web_drf/coreBusinessView/${this.editFormData.id}/`;
- axios
- .put(url, this.editFormData)
- .then(response => {
- console.log("编辑成功", response.data);
- this.editDialogVisible = false;
- this.getData();
- })
- .catch(error => {
- console.error("编辑失败", error);
- });
- }
- });
- }
- }
- };
- </script>
- <style>
- .pagination {
- margin-top: 20px;
- text-align: center;
- }
- </style>
复制代码 业务范围管理页面效果图

(2)业务范围管理系统后端代码views
- from rest_framework.response import Response
- from rest_framework.views import APIView
- from rest_framework import serializers
- from webapp.models import CoreBusiness
- class coreBusinessSerializers(serializers.ModelSerializer):
- class Meta:
- model = CoreBusiness
- fields = '__all__'
- class coreBusinessView(APIView):
- def get(self, request):
- coreBusiness = CoreBusiness.objects.all()
- ser = coreBusinessSerializers(instance=coreBusiness, many=True)
- print(ser.data)
- return Response(ser.data)
- def post(self, request):
- ser = coreBusinessSerializers(data=request.data)
- if ser.is_valid():
- CoreBusiness.objects.create(**ser.validated_data)
- return Response(ser.validated_data)
- else:
- return Response(ser.errors)
- class coreBusinessdetailview(APIView):
- def get(self, request, pk):
- coreBusiness = CoreBusiness.objects.get(pk=pk)
- ser = coreBusinessSerializers(instance=coreBusiness, many=False)
- return Response(ser.data)
- def put(self, request, pk):
- ser = coreBusinessSerializers(data=request.data)
- if ser.is_valid():
- CoreBusiness.objects.filter(pk=pk).update(**ser.validated_data)
- return Response(ser.validated_data)
- else:
- return Response(ser.errors)
- def delete(self, request, pk):
- CoreBusiness.objects.get(pk=pk).delete()
- return Response('删除成功')
复制代码 (3)设置子路由
(4)在主路由中设置该app(主路由跟setting在同一个文件夹)
7.创建数据库表
在恣意一个models中都可以创建数据库表
- from django.db import models
- # 联系我们表
- class Contact(models.Model):
- id = models.AutoField(primary_key=True)
- company_name = models.CharField(max_length=100, verbose_name='公司名称')
- phone = models.CharField(max_length=20, verbose_name='电话')
- address = models.CharField(max_length=200, verbose_name='地址')
- email = models.CharField(max_length=255, verbose_name='邮箱')
- class Meta:
- db_table = 'contact'
复制代码 创建表完成之后举行数据库的迁移,在项目的根目录下的控制台举行
- python manage.py makemigrations
- python manage.py migrate
复制代码 8.启动vue项目
9.打开浏览器访问http://localhost:8080/#/user/login/ 即可登录
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |