首页 > 其他分享 >基于Django+Vue的图书借阅管理系统的设计与实现

基于Django+Vue的图书借阅管理系统的设计与实现

时间:2024-11-04 15:46:54浏览次数:4  
标签:Vue return request APIResponse Django code 借阅 data serializer

项目介绍

这是一个基于Django+Vue开发的图书借阅管理系统。采用B/S架构,后端使用Python语言基于开发,前端使用Vue.js框架进行开发,数据库使用MySQL。

整个系统包括前台和后台两个部分。

系统演示

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="npYPWm7k-1730687051626" src="https://live.csdn.net/v/embed/432448"></iframe>

基于Django+Vue的图书借阅管理系统

系统功能模块

前台功能模块(读者)
  • 登录注册模块
  • 图书管理模块(实现查看图书列表、查询图书、查看详情、收藏、借阅、新书推荐、热门推荐等)
  • 借阅管理模块(实现自己的借阅、归还、续借等)
  • 公告管理(实现查看系统公告)
  • 个人中心模块(实现修改个人信息、修改密码、头像等)
  • 积分管理(实现查看个人积分使用明细等)
后台功能模块(管理员)
  • 数据可视化(实现借阅排行、热门借阅、推荐图书等各种可视化图表)

  • 图书管理(实现图书的添加、删除、修改、查询)

  • 分类管理(实现分类的添加、删除、修改、查询,平台按照不同分类对图书进行管理,如文学、历史、科学等)

  • 标签管理(实现标签的添加、删除、修改、查询)

  • 读者管理(实现读者的添加、删除、修改、查询)

  • 公告管理(实现系统公告的添加、删除、修改、查询,包括图书借阅规则、新书上架通知、系统维护公告等)

  • 借阅管理(实现系统所有借阅的管理)

开发环境

软件包版本
Node16.14.2
MySQL8.0.31
Python3.8
Vue2

系统界面

前台

首页

在这里插入图片描述

我的借阅

在这里插入图片描述

我的积分

在这里插入图片描述

系统公告

在这里插入图片描述

账号安全

在这里插入图片描述

个人设置

在这里插入图片描述

后台

首页

在这里插入图片描述

借阅管理

在这里插入图片描述

图书管理

在这里插入图片描述

分类管理

在这里插入图片描述

标签管理

在这里插入图片描述

用户管理

在这里插入图片描述

公告管理

在这里插入图片描述

源码实现

读者借阅模块后端源码
# Create your views here.
import datetime

from rest_framework.decorators import api_view, authentication_classes

from myapp.auth.authentication import TokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Borrow, Book
from myapp.serializers import BorrowSerializer


@api_view(['GET'])
def list_api(request):
    if request.method == 'GET':
        userId = request.GET.get('userId', -1)
        borrowStatus = request.GET.get('borrowStatus', '')

        borrows = Borrow.objects.all().filter(user=userId).filter(status__contains=borrowStatus).order_by('-borrow_time')
        serializer = BorrowSerializer(borrows, many=True)
        return APIResponse(code=0, msg='查询成功', data=serializer.data)


@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def create(request):
    """
    创建借书
    """

    data = request.data.copy()
    if data['user'] is None or data['book'] is None:
        return APIResponse(code=1, msg='参数错误')

    book = Book.objects.get(pk=data['book'])
    if book.repertory <= 0:
        return APIResponse(code=1, msg='库存不足')

    borrows = Borrow.objects.filter(book=data['book']).filter(user=data['user']).filter(status='1')
    if len(borrows) > 0:
        return APIResponse(code=1, msg='您已经借过该书了')

    create_time = datetime.datetime.now()

    data['status'] = '1'
    data['delayed'] = False
    data['create_time'] = create_time
    data['expect_time'] = create_time + datetime.timedelta(days=30)
    serializer = BorrowSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        # 减库存
        book.repertory = book.repertory - 1
        book.save()

        return APIResponse(code=0, msg='借书成功', data=serializer.data)
    else:
        print(serializer.errors)
        return APIResponse(code=1, msg='借书失败')


@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def return_book(request):
    """
    还书
    """
    try:
        pk = request.GET.get('id', -1)
        borrow = Borrow.objects.get(pk=pk)
    except Borrow.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    data = {
        'status': 2
    }
    serializer = BorrowSerializer(borrow, data=data)
    if serializer.is_valid():
        serializer.save()
        # 加库存
        bookId = request.data['book']
        book = Book.objects.get(pk=bookId)
        book.repertory = book.repertory + 1
        book.save()

        # 加积分
        borrow.user.score = borrow.user.score + 1
        borrow.user.save()

        return APIResponse(code=0, msg='还书成功', data=serializer.data)
    else:
        print(serializer.errors)
        return APIResponse(code=1, msg='更新失败')


@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def delay(request):

    try:
        pk = request.GET.get('id', -1)
        borrow = Borrow.objects.get(pk=pk)
    except Borrow.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    if (borrow.expect_time - borrow.borrow_time).days + 1 >= 90:
        return APIResponse(code=1, msg='已超最大延期次数')
    else:
        data = {
            "delayed": True,
            "expect_time": borrow.expect_time + datetime.timedelta(days=30),
            "status": '3'
        }
        serializer = BorrowSerializer(borrow, data=data)
        if serializer.is_valid():
            serializer.save()
            return APIResponse(code=0, msg='延期成功', data=serializer.data)
        else:
            print(serializer.errors)
            return APIResponse(code=1, msg='延期失败')

读者用户模块后端源码
# Create your views here.


from rest_framework.decorators import api_view, authentication_classes
from django.utils import timezone

from myapp import utils
from myapp.auth.authentication import TokenAuthtication
from myapp.handler import APIResponse
from myapp.models import User, Borrow
from myapp.serializers import UserSerializer, LoginLogSerializer, BorrowSerializer
from myapp.utils import md5value


def make_login_log(request):
    try:
        username = request.data['username']
        data = {
            "username": username,
            "ip": utils.get_ip(request),
            "ua": utils.get_ua(request)
        }
        serializer = LoginLogSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
        else:
            print(serializer.errors)
    except Exception as e:
        print(e)


@api_view(['POST'])
def login(request):
    username = request.data['username']
    password = utils.md5value(request.data['password'])

    users = User.objects.filter(username=username, password=password)
    if len(users) > 0:
        user = users[0]

        if user.role in ['1', '3']:
            return APIResponse(code=1, msg='该帐号为后台管理员帐号')

        # 计算用户积分
        my_borrow = Borrow.objects.filter(user=user.id)
        now = timezone.now()
        returns = my_borrow.filter(status=2)
        overdues = my_borrow.exclude(status=2).filter(expect_time__lt=now)
        return_count = returns.count()
        overdue_count = overdues.count()
        score = 100 + return_count - overdue_count * 10
        user.score = score
        if user.score == 0:
            return APIResponse(code=1, msg='积分不足, 无法登录系统!')

        data = {
            'username': username,
            'password': password,
            'token': md5value(username)  # 生成令牌
        }
        serializer = UserSerializer(user, data=data)
        if serializer.is_valid():
            serializer.save()
            make_login_log(request)
            return APIResponse(code=0, msg='登录成功', data=serializer.data)
        else:
            print(serializer.errors)

    return APIResponse(code=1, msg='用户名或密码错误')


@api_view(['POST'])
def register(request):
    username = request.data.get('username', None)
    password = request.data.get('password', None)
    repassword = request.data.get('repassword', None)
    if not username or not password or not repassword:
        return APIResponse(code=1, msg='用户名或密码不能为空')
    if password != repassword:
        return APIResponse(code=1, msg='密码不一致')
    users = User.objects.filter(username=username)
    if len(users) > 0:
        return APIResponse(code=1, msg='该用户名已存在')

    data = {
        'username': username,
        'password': password,
        'role': 2,  # 角色2
        'status': 0,
        'score': 100
    }
    data.update({'password': utils.md5value(request.data['password'])})
    serializer = UserSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        return APIResponse(code=0, msg='创建成功', data=serializer.data)
    else:
        print(serializer.errors)

    return APIResponse(code=1, msg='创建失败')


@api_view(['GET'])
def info(request):
    if request.method == 'GET':
        pk = request.GET.get('id', -1)
        user = User.objects.get(pk=pk)
        
        # 计算用户积分,并统计还书和预期数据
        my_borrow = Borrow.objects.filter(user=pk)
        now = timezone.now()
        returns = my_borrow.filter(status=2)
        overdues = my_borrow.exclude(status=2).filter(expect_time__lt=now)
        return_count = returns.count()
        overdue_count = overdues.count()
        score = 100 + return_count - overdue_count * 10
        user.score = score
        serializer = UserSerializer(user)
        data = {
            'info': serializer.data,
            'returns': BorrowSerializer(returns, many=True).data,
            'overdues': BorrowSerializer(overdues, many=True).data
        }
        
        return APIResponse(code=0, msg='查询成功', data=data)


@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def update(request):
    try:
        pk = request.GET.get('id', -1)
        user = User.objects.get(pk=pk)
    except User.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    data = request.data.copy()
    if 'username' in data.keys():
        del data['username']
    if 'password' in data.keys():
        del data['password']
    if 'role' in data.keys():
        del data['role']
    serializer = UserSerializer(user, data=data)
  
    if serializer.is_valid():
        serializer.save()
        return APIResponse(code=0, msg='更新成功', data=serializer.data)
    else:
        print(serializer.errors)

    return APIResponse(code=1, msg='更新失败')


@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def updatePwd(request):

    try:
        pk = request.GET.get('id', -1)
        user = User.objects.get(pk=pk)
    except User.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    password = request.data.get('password', None)
    newPassword1 = request.data.get('newPassword1', None)
    newPassword2 = request.data.get('newPassword2', None)

    if not password or not newPassword1 or not newPassword2:
        return APIResponse(code=1, msg='不能为空')

    if user.password != utils.md5value(password):
        return APIResponse(code=1, msg='原密码不正确')

    if newPassword1 != newPassword2:
        return APIResponse(code=1, msg='两次密码不一致')

    data = request.data.copy()
    data.update({'password': utils.md5value(newPassword1)})
    serializer = UserSerializer(user, data=data)
    if serializer.is_valid():
        serializer.save()
        return APIResponse(code=0, msg='更新成功', data=serializer.data)
    else:
        print(serializer.errors)

    return APIResponse(code=1, msg='更新失败')
读者评论模块后端源码
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes

from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Comment
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import CommentSerializer


@api_view(['GET'])
def list_api(request):
    if request.method == 'GET':
        bookId = request.GET.get("bookId", None)
        order = request.GET.get("order", 'recent')

        if bookId:
            if order == 'recent':
                orderBy = '-comment_time'
            else:
                orderBy = '-like_count'

            comments = Comment.objects.select_related("book").filter(book=bookId).order_by(orderBy)
            serializer = CommentSerializer(comments, many=True)
            return APIResponse(code=0, msg='查询成功', data=serializer.data)
        else:
            return APIResponse(code=1, msg='bookId不能为空')

@api_view(['GET'])
def list_my_comment(request):
    if request.method == 'GET':
        userId = request.GET.get("userId", None)
        order = request.GET.get("order", 'recent')

        if userId:
            if order == 'recent':
                orderBy = '-comment_time'
            else:
                orderBy = '-like_count'

            comments = Comment.objects.select_related("book").filter(user=userId).order_by(orderBy)
            serializer = CommentSerializer(comments, many=True)
            return APIResponse(code=0, msg='查询成功', data=serializer.data)
        else:
            return APIResponse(code=1, msg='userId不能为空')

@api_view(['POST'])
def create(request):
    serializer = CommentSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return APIResponse(code=0, msg='创建成功', data=serializer.data)
    else:
        print(serializer.errors)

    return APIResponse(code=1, msg='创建失败')


@api_view(['POST'])
def delete(request):
    try:
        ids = request.GET.get('ids')
        ids_arr = ids.split(',')
        Comment.objects.filter(id__in=ids_arr).delete()
    except Comment.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    return APIResponse(code=0, msg='删除成功')


@api_view(['POST'])
def like(request):
    try:
        commentId = request.GET.get('commentId')
        comment = Comment.objects.get(pk=commentId)
        comment.like_count += 1
        comment.save()
    except Comment.DoesNotExist:
        return APIResponse(code=1, msg='对象不存在')

    return APIResponse(code=0, msg='推荐成功')

更多源码

由于文字篇幅限制,更多源码私信作者领取!!!

标签:Vue,return,request,APIResponse,Django,code,借阅,data,serializer
From: https://blog.csdn.net/m0_51181022/article/details/143478042

相关文章

  • vue节流和防抖的实现
    防抖场景search搜索时,用户在不断输入值时,用防抖来节约请求资源。输入框动态搜索@change='handleSearch'asyncgetList(val){letparam;if(val&&val!==undefined){param={parameter:val}}const{data}=awaitgetLists(para......
  • (开题报告)django+vue电影推荐系统APP源码+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景关于电影推荐系统的研究,现有研究多集中在推荐算法的优化、单一框架的实现等方面。专门针对django+vue组合框架构建电影推荐系统APP的研......
  • 基于ssm+vue基于web的软件资源库的设计与实现(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景在信息化高速发展的今天,软件资源的管理与共享成为提升工作效率、促进知识传播的重要手段。关于软件资源库的设计与实现,现有研究主要以大型企业内部的......
  • 基于ssm+vue基于Web的社团管理信息系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景在当今信息化高速发展的时代,社团作为高校及社区文化的重要组成部分,其管理效率与信息化水平直接关系到社团活动的质量与成员参与的积极性。关于社团管......
  • 基于ssm+vue基于web的师生互动平台(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景在教育信息化快速发展的背景下,师生互动作为提升教学质量和学习效果的关键环节,日益受到重视。当前,关于师生互动的研究主要集中在传统课堂环境下的互动......
  • 基于ssm+vue基于web的社团管理系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景随着信息技术的飞速发展,基于Web的管理系统已广泛应用于各个领域,极大地提高了管理效率和用户体验。关于社团管理的研究,现有研究主要以传统管理方式为......
  • (开题报告)django+vue基于的商品销售信息系统源码+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景随着互联网技术的迅猛发展,电子商务在全球范围内蓬勃发展。关于商品销售信息管理系统的研究,现有研究主要以传统的销售模式与简单的信息......
  • VUE - 配置根目录(用@代表src目录)
    VUE-配置根目录(用@代表src目录)在Vue项目中,@ 符号通常被用作一个别名,代表项目中的 src 目录。这通常是通过webpack的resolve.alias配置实现的。例如,如果你有一个Vue组件在 src/components 目录下,你可以在这个组件中这样导入它:importMyComponentfrom'@/compon......
  • PHP图书馆借阅管理系统-计算机毕业设计源码01649
    基于HTML5+CSS的图书馆借阅管理系统的设计与实现摘 要随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理。本文旨在设计和实现基于SSM框架和HTML技术的图书......