基于Python+Django+Vue+Mysql前后端分离的图书管理系统

news2024/11/15 7:48:45

利用空闲休息时间开始自己写了一套图书管理系统。现将源码开源,项目遇到问题

Python+Django+Vue图书管理系统开发全流程

大家好,我是程序员科科,这是我开源的基于Python+Django+Vue的图书管理系统

希望可以帮助想学前后端分离的同学

项目中遇到问题欢迎添加微信python_kk一起探讨

如果感觉项目还不错,请帮我点个star~

项目运行截图

首页

出版社

图书

作者

登录

怎么运行项目

前端

npm install

npm run dev

后端

使用虚拟环境

python manage.py runserver 127.0.0.1:8000

前端8080端口,后端8000端口

1、pycharm创建django项目(使用虚拟环境,避免项目干扰)

2、配置总路由

from django.urls import path,re_path,include
from django_vue_tushu.settings import MEDIA_ROOT
from django.contrib import admin
from dvtushu import views
from django.views.static import serve
from rest_framework.documentation import include_docs_urls

urlpatterns = [
    # 接口文档
    path('docs/', include_docs_urls(title='tushu')),
    path('admin/', admin.site.urls),
    path('django_vue_tushu/', include('dvtushu.urls'),name='dvtushu'),
    # 图片上传接口
    re_path('img_upload/', views.img_uploadApiview.as_view()),
    # 前端查找图片地址
    re_path('upimg/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT})
]

3、配置子路由

from django.urls import path,re_path
from . import views

urlpatterns = [
    # path('/', ),
]

3、启动项目

python manage.py runserver 127.0.0.1 或者 pycharm 启动

4、安装依赖(有默认前后端分离所需依赖)

pip install -r .\utils\requ.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

依赖放入 /utils/requirements.txt

asgiref==3.7.2
certifi==2024.2.2
cffi==1.15.1
charset-normalizer==3.3.2
coreapi==2.3.3
coreschema==0.0.4
cryptography==42.0.2
Django==3.2.23
django-cors-headers==4.1.0
django-filter==23.5
django-rest-swagger==2.2.0
djangorestframework==3.14.0
djangorestframework-jwt==1.11.0
drf-yasg==1.21.7
idna==3.6
inflection==0.5.1
install==1.3.5
itypes==1.2.0
Jinja2==3.1.3
MarkupSafe==2.1.5
openapi-codec==1.3.2
packaging==24.0
pycparser==2.21
PyJWT==1.7.1
PyMySQL==1.1.0
pytz==2023.4
PyYAML==6.0.1
requests==2.31.0
simplejson==3.19.2
sqlparse==0.4.4
typing_extensions==4.7.1
uritemplate==4.1.1
urllib3==1.26.12

5、修改数据库

djvue_school_shop/settings.py

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "HOST": "127.0.0.1",
        "PORT": 3306,
        "USER": "root",
        "PASSWORD": "123456",
        "NAME": "dvlvyou",
    }
}

djvue_school_shop/init.py

import pymysql
pymysql.install_as_MySQLdb()

6、设置settings相关内容

(1):添加跨域和djangorestframework

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djvue_schoolshop.apps.DjvueSchoolshopConfig',
    'corsheaders',
    'rest_framework',
]

(2):添加跨域中间件和注释csrf

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',
    'corsheaders.middleware.CorsMiddleware',
]

(3):时间中国

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

(4):添加跨域请求头和请求地址相关

# # # CORS组的配置信息
# CORS_ORIGIN_WHITELIST = (
#     #'www.hippo.cn:8080', #如果这样写不行的话,就加上协议(http://www.hippo.cn:8080,因为不同的corsheaders版本可能有不同的要求)
#     'http://127.0.0.1:8080',
# )
CORS_ORIGIN_ALLOW_ALL = True

# 是否允许ajax跨域请求时携带cookie,False表示不用,我们后面也用不到cookie,所以关掉它就可以了,以防有人通过cookie来搞我们的网站
CORS_ALLOW_CREDENTIALS = False
# 请求方法
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)
# 允许的请求头,不能用*,要写具体的请求头,不然Vue会跨域失败,在这里坑了我好久好久MD
CORS_ALLOW_HEADERS = (
'*'
)

(5):添加djangorestframework全局处理类

REST_FRAMEWORK = {
    # 异常处理
    # 'EXCEPTION_HANDLER': 'hippo_api.utils.exceptions.custom_exception_handler',

    # jwt
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        # 'dj_vue_jc.TokenAuthtication.TokenAuthtication',
    ),
}

(6):添加媒体上传文件配置

# 指定文件获取的url路径
MEDIA_URL = "/upimg/"

# 文件上传的保存路径
MEDIA_ROOT = BASE_DIR / 'upimg'

7、创建媒体文件

upimg

8、urls中设置前端文件图片上传地址和访问地址

from django.urls import path,re_path,include
from django_vue_tushu.settings import MEDIA_ROOT
from django.contrib import admin
from dvtushu import views
from django.views.static import serve
from rest_framework.documentation import include_docs_urls

urlpatterns = [
    # 接口文档
    path('docs/', include_docs_urls(title='tushu')),
    path('admin/', admin.site.urls),
    path('django_vue_tushu/', include('dvtushu.urls'),name='dvtushu'),
    # 图片上传接口
    re_path('img_upload/', views.img_uploadApiview.as_view()),
    # 前端查找图片地址
    re_path('upimg/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT})
]

9、views 设置 图片上传接口

# 前台返回格式
ret = {
    "data": {},
    "meta": {
        "status": 200,
        "message": "注册成功"
    }
}

# 图片上传接口
class img_uploadApiview(View):
    def get(self, request):
        return JsonResponse(data={'code': 200, 'message': '方法测试'})

    # 图片上传接口通过 request.data 可以接收到前端发来的
    def post(self,request):
        response = {}
        dataduixiang = request.POST.get('data','')
        file = request.FILES.get('file')
        # try:
        # 构造图片保存路径 路径为<USER_AVATAR_ROOT + 文件名>
        # USER_AVATAR_ROOT刚刚在settings.py中规定过,需要导入进来
        file_path = os.path.join(settings.MEDIA_ROOT, file.name)
        # 保存图片
        print(dataduixiang,file)
        with open(file_path, 'wb+') as f:
            f.write(file.read())
            f.close()
        response['file'] = file.name  # 返回新的文件名
        response['code'] = 0
        response['msg'] = "图片上传成功!"
        return JsonResponse(data={'code': 200, 'message': '上传成功', 'data': response})

10、启动项目

python manage.py runserver 127.0.0.1:8000

11、数据库设计

from django.db import models

# Create your models here.

# 管理表
class Guanli(models.Model):
    username = models.CharField(max_length=255)
    password = models.TextField()

from django.db import models

# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书籍名称")
    price = models.IntegerField(verbose_name="价格")
    # pub_date = models.DateField(verbose_name="出版日期")
    img_url = models.CharField(max_length=255, null=True,blank=True,verbose_name="")
    bread = models.IntegerField(verbose_name="阅读量")
    bcomment = models.IntegerField(verbose_name="评论量")
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE, verbose_name="出版社")
    authors = models.ManyToManyField("Author",verbose_name="作者")

    def __str__(self):
        return self.title


class Publish(models.Model):
    name = models.CharField(max_length=32, verbose_name="出版社名称")
    email = models.EmailField(verbose_name="出版社邮箱")

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者")
    age = models.IntegerField(verbose_name="年龄")

    def __str__(self):
        return self.name

12、迁移

python manage.py makemigrations

python manage.py migrate

13、登录接口

url

# 登录接口
path('logintest/', views.LoginView.as_view()),

view

from .TokenAuthtication import TokenAuthtication
from rest_framework.response import Response
from django.core.paginator import Paginator
from rest_framework.views import APIView
from django.views import View
from django.http import HttpResponse,JsonResponse
from django_vue_tushu import settings
from .Serializer import *
from .models import *
import datetime
import jwt
import os

class LoginView(APIView):
    def post(self, request):
        ret = {
            "data": {},
            "meta": {
                "status": 200,
                "message": ""
            }
        }
        try:
            username = request.data["username"]
            password = request.data["password"]
            value = int(request.data["value"])

            if value == 1:
                user = Guanli.objects.filter(username=username,password=password)
                print(username,password,value,user)
                if user.count == 0:
                    ret["meta"]["status"] = 500
                    ret["meta"]["message"] = "用户不存在或密码错误"
                    return Response(ret)
                elif user and user.first().password:
                    dict = {
                        "exp": datetime.datetime.now() + datetime.timedelta(days=1),  # 过期时间
                        "iat": datetime.datetime.now(),  # 开始时间
                        "id": user.first().id,
                        "username": user.first().username,
                    }
                    token = jwt.encode(dict, settings.SECRET_KEY, algorithm="HS256")
                    ret["data"]["token"] = token
                    ret["data"]["username"] = user.first().username
                    ret["data"]["user_id"] = user.first().id
                    # 这里需要根据数据库判断是不是管理员
                    ret["data"]["isAdmin"] = 1
                    ret["meta"]["status"] = 200
                    ret["meta"]["message"] = "登录成功"
                    print(ret,type(ret))
                    return Response(ret)
                else:
                    ret["meta"]["status"] = 500
                    ret["meta"]["message"] = "用户不存在或密码错误"
                    return Response(ret)
        except Exception as error:
            print(error)
            ret["meta"]["status"] = 500
            ret["meta"]["message"] = "用户不存在或密码错误"
            return Response(ret)

14、创建Serializer

djvue_schoolshop

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from . import models

class GuanliModelSerializers(ModelSerializer):
    """管理员信息模型序列化器"""
    username = serializers.CharField(read_only=True)

    class Meta:
        model = models.Guanli
        fields = '__all__'

class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Publish
        fields = "__all__"

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Author
        fields = "__all__"

class BookInfoModelSerializermodel(serializers.ModelSerializer):
    # 使用PublishSerializer作为publish字段的嵌套序列化器
    publish = PublishSerializer(read_only=True)
    # 使用主键字段类型 并且将publish_id设置为"只写",也就是读取的时候不会返回!
    publish_id = serializers.PrimaryKeyRelatedField(queryset=models.Publish.objects.all(), source='publish',
                                                    write_only=True)

    # 使用AuthorSerializer作为author字段的嵌套序列化器
    authors = AuthorSerializer(read_only=True, many=True)
    # 使用主键字段类型 并且将author_id设置为"只写",也就是读取的时候不会返回!
    authors_id = serializers.PrimaryKeyRelatedField(queryset=models.Author.objects.all(), source='authors',
                                                    write_only=True, many=True)

    class Meta:
        model = models.Book
        # fields = ['id', 'title', 'price', 'pub_date', 'bread', 'bcomment', 'publish_id', 'publish', 'authors',
        #           'authors_id']
        fields = "__all__"
        # depth = 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2034545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

积极创新模式,推动智慧场馆建设

智慧场馆是指基于信息技术应用的场馆建设模式&#xff0c;利用物联网、云计算、大数据分析等技术手段&#xff0c;实现场馆资源的管理优化、运营效率的提升以及用户体验的改善。智慧场馆在我国得到了广泛的政策支持和推动&#xff0c;政府出台了一系列鼓励智慧场馆建设的政策措…

Java SIP Client

采用JAIN SIP API实现一个SIP客户端实现向SIP服务器注册。SIP服务器可以为FreeSWITCH也可以为满足GB28181的SIP平台。话不多说直接看注册流程图&#xff1a; 代码实现&#xff1a; 创建maven工程添加依赖 <dependencies><dependency><groupId>javax.sip</…

Apple Maps现在可在Firefox和Mac版Edge浏览器中使用

Apple Maps最初只能在 Windows 版 Safari、Chrome 浏览器和 Edge 浏览器上运行&#xff0c;现在已在其他浏览器上运行&#xff0c;包括 Mac 版 Firefox 和 Edge。经过十多年的等待&#xff0c;Apple Maps于今年 7 月推出了新版地图应用的测试版&#xff0c;但只能在有限的浏览器…

哈希表 - 三数之和

15. 三数之和 方法一&#xff1a;排序双指针 /*** param {number[]} nums* return {number[][]}*/ var threeSum function(nums) {const res [], len nums.length;// 将数组排序nums.sort((a, b) > a - b)for (let i 0; i < len; i) {let l i 1, r len - 1, iNum…

什么是令牌桶算法?工作原理是什么?使用它有哪些优点和注意事项?

大家好&#xff0c;我是鸭鸭&#xff01; 此答案节选自鸭鸭最近弄的面试刷题神器面试鸭 &#xff0c;更多大厂常问面试题&#xff0c;可以点击下面的小程序进行阅读哈&#xff01; 目前这个面试刷题小程序刚出&#xff0c;有网页和小程序双端可以使用&#xff01; 回归面试题…

网络初学者必备:100个基础知识全掌握

网络安全学习路线 如果你对网络安全入门感兴趣&#xff0c;那么你需要的话可以点击这里网络安全重磅福利&#xff1a;入门&进阶全套282G学习资源包免费分享&#xff01; 或者扫描下方csdn官方合作二维码获取哦&#xff01; 1 什么是链接? 链接是指两个设备之间的连接。…

OpenCV 基本使用

OpenCV 基本使用 参考教程&#xff1a; GitHub - gaoxiang12/slambook2: edition 2 of the slambook 1. 安装 OpenCV 1.1 下载 OpenCV 参考教程&#xff1a; 无法定位软件包libjasper-dev的解决办法-CSDN博客 视觉slam14讲ch5 opencv安装 ubuntu20.04_libvtk5-dev-CSDN博…

机器学习——聚类算法K-Means

目录 一、初识聚类 1. 认识聚类算法 2. 聚类的流程 3. 簇内误差平方和 Inertia越小模型越好吗&#xff1f; 二、KMeans介绍 1. 重要参数n_clusters 2. 模型评估指标 &#xff08;1&#xff09;真实标签己知的时候 &#xff08;2&#xff09;真实标签未知的时候 三、s…

Tomcat 最大连接数实现原理

spring boot 内置tomcat设置连接数 max-connections: 5 server:port: 9898servlet:context-path: /testtomcat:connection-timeout: 5000max-connections: 5accept-count: 5 ##初始化连接数量connectionLimitLatch protected LimitLatch initializeConnectionLatch() {if (ma…

【区块链+食品安全】农业产业全过程溯源云平台 | FISCO BCOS应用案例

近年来&#xff0c;食品安全问题频发&#xff0c;尤其疫情期间&#xff0c;海鲜、冷冻畜牧产品的入口安全成为大众关注焦点&#xff0c;追溯、确保相关产品生产、运输、售卖等环节的信息真实、有效&#xff0c;成为保证食品安全的核心环节。浙江天演维真网络科技股份有限公司基…

基于ICMP(Ping)的多线程网络通道监视程序(QT)开发

基于ICMP(Ping)的多线程网络通道监视程序(QT)开发 1、 ICMP原理简介 可参考 ICMP(Ping)功能原理及其C实现简介 。 2、 网络通道监视程序开发 设计原理&#xff1a; 通过PING 功能实现服务器、交换机、网闸等设备的网络检测&#xff0c;判断网络的否可达和TTL计算 。 具备功…

微深节能 库区智能化无人天车管理系统 格雷母线

格雷母线在库区智能化无人天车管理系统的应用中&#xff0c;发挥了至关重要的作用。 一、系统构成与原理 系统构成&#xff1a; 格雷母线高精度位移测量系统主要由格雷母线、天线箱、地址解码器、地址编码器四个核心部分组成。这些组件协同工作&#xff0c;实现对移动设备的精确…

c++41两头堵模型

直接拷到自己的内存空间 字符串反转 递归&#xff1a;参数的入栈模型 函数的调用模型 先被调用的模型后执行 向局部变量拷贝内存 传两个参数 做函数结果

【解析几何笔记】1.课程介绍与要求

听的是B站UP主唐小谦的解析几何课&#xff0c;万年的老计算机专业人也想学数学OWO。 1. 课程介绍与要求 前面都是老师的课程介绍&#xff0c;从板书证明开始记 【证明】在三角形ABC中&#xff0c;D为BC边的中点&#xff0c;证明&#xff1a; ∠ ABC 9 0 ∘ \angle \text{ABC…

出现 AWS ECS 错误:集群中未找到容器实例处理办法?

使用部署docker容器映像&#xff0c;但未创建 EC2 实例的情况下。出现下面错误提示。 “调用 RunTask 操作时发生客户端错误 (InvalidParameterException)&#xff1a;在您的集群中未找到容器实例。” 经过以下的步骤&#xff1a; 1.将 Docker 映像从 Ubuntu 推送到我的 Amazo…

c++ - 特殊类设计

文章目录 一、设计一个不允许拷贝的类二、设计一个只能在堆上实例对象的类三、设计一个只能在栈上创建对象的类四、设计一个不能被继承的类五、设计一个只能创建一个对象的类&#xff08;单例模式&#xff09; 一、设计一个不允许拷贝的类 1、方法一&#xff1a;将拷贝构造和赋…

在Windows上配置VSCode MinGW+CMake(包括C++多线程编程的两套API:posix和win32)

创建目录 首先&#xff0c;需要电脑上安装VSCode, 并且创建三个文件夹&#xff1a;cmake、MinGW-posix、MinGW-w32 文件下载 下载posix-seh posix和win32分别是c多线程变成的两套API,可根据不同需求安装&#xff0c;现在先下载配置环境需要的几个文件 百度搜索MinGW-64 点…

Django 链接MySQL数据库,报错Did you install mysqlclient?

据说是在python3里面&#xff0c;已经用pymysql替换了MySQLdb来进行数据库连接 所以&#xff0c;先安装pymysql pip install pymysql之后为了测试这个问题是否和mysql-connector-c有关系&#xff0c;我提前把这个应用给卸了。 之后在整个项目根目录的init文件内写入以下内容 im…

在docker中进行日志切割

先在Linux中安装docker&#xff0c;然后在docker中安装appnode面板&#xff0c;并进行docker网络端口映射。接着进入docker&#xff0c;进行nginx日志切割。 安装docker 第一步&#xff0c;卸载旧版本docker。 若系统中已安装旧版本docker&#xff0c;则需要卸载旧版本docke…

大模型在资源全生命周期的应用探索

资源全生命周期管理的传统价值 运营商的网络涉及接入网、数据网、承载网、核心网、传输网、无线网、光缆网、云专网、动力网、业务平台等十数类大专业。网络资源的全生命周期体现在以下六大生产活动环节&#xff1a;网络规划→网络设计→网络工程建设→网络资源的投入使用→网络…