1. 系统简介
该实验设计开发一个简单的图书管理数据库系统,包括图书馆内书籍的信息、学校在校师生的信息以及师生的借阅信息。此系统用户面向图书管理员和借阅读者,图书馆管理员可以完成图书、读者等基本信息的增加、删除和修改、查看;读者可以进行图书的借阅、查看、预约等操作。构建基于B/S架构,MySQL数据库为基础,应用Django框架建设过程和方法。本系统主要包含以下基本功能,主要是前台展示和后台管理两部分,其中前台展示包括登陆模块、首页展示、书籍检索、分类查看等。
系统开发技术及工具:Python Django HTML MySQL数据库 Windows11系统 PyCharm
- 2.系统分析
- 2.1 功能简介:
2.2 功能需求描述
借阅功能:
图书出借时考虑的问题:
读者是否因为超期、罚款等情况被关闭了借阅权限;
读者是否已经借满其限额。
该书是否不在库中;
如果不存在以上情况,则可以出借。
预约功能:
读者想借的书如果不在库中(已经被出借),读者可以预约该图书
读者管理功能:
对读者信息进行查看、添加、修改、删除。将读者分为不同类别,赋以不同权限。
系统管理功能:
对管理员的登录账号、密码进行添加、修改、删除。
违规管理功能:
对违规信息进行查看、添加、修改、删除。
3系统数据库设计
3.1系统概念模型设计
数据库需要描述的数据信息包括以下几种:
(1)读者信息
(2)书籍信息
(3)管理员信息
(4)读者与书籍之间的关系(借阅关系E-R图)
3.2数据库的详细设计
3.2.1数据表的详细设计
图书管理系统由三个实体:图书实体,读者实体,管理员实体,图书种类实体组成,共六个表如下:
1****、书籍表
属性:图书编号,ISBN,书名,作者,出版社,出版日期,价格,学科类型,藏书类型,总量,余量
主键:图书编号
2****、读者表
属性:读者编号,读者姓名,联系电话,邮箱地址,所在系,权限状况
主键:读者编号
3****、管理员用户表
属性:编号,账号,密码,姓名
4****、借阅表
属性:图书编号,读者编号,借阅日期,应还日期
5****、预约信息
属性:编号,图书编号,读者编号,预约日期
6****、违规表
属性:编号,读者编号,图书编号,逾期(0/1),破坏书籍(0/1)
3.2.2 E-R图
1、图书实体E-R图
图书具有图书编号,ISBN,书名,作者,出版社,出版日期,价格,总量,余量等九个属性,便于读者在使用图书馆管理系统时,更加准确的定位到所选图书的位置,了解图书的信息。也可以方便读者利用碎片化的信息,从大量的图书中筛选自己可能心仪图书。
2、图书馆管理员实体E-R图
图书管理员实体具有编号,账号,密码,姓名,联系方式
3、读者实体E-R图
读者具有读者编号,读者姓名,联系电话,邮箱地址,备注,便于图书管理员及时的维护管理借阅系统,明确每一本图书的去向,对与图书馆图书的情况有一个把握。维护图书管理系统的正常运行。
4、总体E-R图
在图书管理系统中,一名读者可以借阅多本图书,多名图书管理员同时管理多本图书,一名读书管理员可以同时管理多名读者。通过实体之间的相互联系,构成了图书管理系统的总体E-R图。
3.3表设计
1、读者表(reader)
列名
类型
长度
约束
备注
id
int
主键
编号
reader_id
int
11
学号
password
char
20
密码
name
char
10
读者姓名
telephone
char
15
联系电话
char
30
邮箱地址
dept
char
20
所在院系
right
int
1
借阅权限(0或1)
2、图书表(book)
列名
类型
长度
约束
备注
id
int
主键
编号
bookname
char
20
书籍名称
author
char
20
书籍作者
pubdate
date
出版日期
publish
char
30
出版社
price
decimal
7,2
非空
价格
ISBN
char
17
非空
书籍ISBN码
bookclass
int
11
外键
学科类型
total
int
非空
总量
margin
int
非空
余量
booktype
int
11
外键
藏书类型
- 管理员用户表(admin)
列名
类型
长度
约束
备注
id
Int
主键
- 管理员编号
usernum
Char
20
- 管理员账号
password
Char
11
- 账号密码
username
char
10
管理员姓名
4.借阅表(borrow)
列名
类型
长度
约束
备注
id
int
主键
借阅编号
readerid
int
读者编号
bookid
int
图书编号
borrowdate
date
出借日期
due
date
应还日期
5.预约表(preconcert)
列名
类型
长度
约束
备注
id
int
主键
预约编号
readerid
int
读者编号
bookid
int
图书编号
predate
date
预约日期
6.违规表(break_rule)
列名
类型
长度
约束
备注
id
int
主键
违规编号
reader_id
int
读者编号
book_id
int
图书编号
verdue
int
逾期(0或1)
destory
int
破坏书籍(0或1)
3配置环境
3.1安装和配置环境
3.3表设计
1、读者表(reader)
列名
类型
长度
约束
备注
id
int
主键
编号
reader_id
int
11
学号
password
char
20
密码
name
char
10
读者姓名
telephone
char
15
联系电话
char
30
邮箱地址
dept
char
20
所在院系
right
int
1
借阅权限(0或1)
2、图书表(book)
列名
类型
长度
约束
备注
id
int
主键
编号
bookname
char
20
书籍名称
author
char
20
书籍作者
pubdate
date
出版日期
publish
char
30
出版社
price
decimal
7,2
非空
价格
ISBN
char
17
非空
书籍ISBN码
bookclass
int
11
外键
学科类型
total
int
非空
总量
margin
int
非空
余量
booktype
int
11
外键
藏书类型
- 管理员用户表(admin)
列名
类型
长度
约束
备注
id
Int
主键
- 管理员编号
usernum
Char
20
- 管理员账号
password
Char
11
- 账号密码
username
char
10
管理员姓名
4.借阅表(borrow)
列名
类型
长度
约束
备注
id
int
主键
借阅编号
readerid
int
读者编号
bookid
int
图书编号
borrowdate
date
出借日期
due
date
应还日期
5.预约表(preconcert)
列名
类型
长度
约束
备注
id
int
主键
预约编号
readerid
int
读者编号
bookid
int
图书编号
predate
date
预约日期
6.违规表(break_rule)
列名
类型
长度
约束
备注
id
int
主键
违规编号
reader_id
int
读者编号
book_id
int
图书编号
verdue
int
逾期(0或1)
destory
int
破坏书籍(0或1)
3配置环境
3.1安装和配置环境
3.3表设计
1、读者表(reader)
列名
类型
长度
约束
备注
id
int
主键
编号
reader_id
int
11
学号
password
char
20
密码
name
char
10
读者姓名
telephone
char
15
联系电话
char
30
邮箱地址
dept
char
20
所在院系
right
int
1
借阅权限(0或1)
2、图书表(book)
列名
类型
长度
约束
备注
id
int
主键
编号
bookname
char
20
书籍名称
author
char
20
书籍作者
pubdate
date
出版日期
publish
char
30
出版社
price
decimal
7,2
非空
价格
ISBN
char
17
非空
书籍ISBN码
bookclass
int
11
外键
学科类型
total
int
非空
总量
margin
int
非空
余量
booktype
int
11
外键
藏书类型
- 管理员用户表(admin)
列名
类型
长度
约束
备注
id
Int
主键
- 管理员编号
usernum
Char
20
- 管理员账号
password
Char
11
- 账号密码
username
char
10
管理员姓名
4.借阅表(borrow)
列名
类型
长度
约束
备注
id
int
主键
借阅编号
readerid
int
读者编号
bookid
int
图书编号
borrowdate
date
出借日期
due
date
应还日期
5.预约表(preconcert)
列名
类型
长度
约束
备注
id
int
主键
预约编号
readerid
int
读者编号
bookid
int
图书编号
predate
date
预约日期
6.违规表(break_rule)
列名
类型
长度
约束
备注
id
int
主键
违规编号
reader_id
int
读者编号
book_id
int
图书编号
verdue
int
逾期(0或1)
destory
int
破坏书籍(0或1)
3配置环境
3.1安装和配置环境
选择Pycharm工具进行本次项目的制作
- 创建django项目
目录说明:
manage.py:一个命令行工具,可以说Django项目就是从这个文件开始执行的。
_init _.py:一个空文件,表示mytest应该被看做一个python包;
settings.py:整个项目的配置参数文件;
urls.py:项目的URL声明,一般项目的顶级url正则匹配放置在这里;
wsgi.py:项目与WSGI兼容的Web服务器入口;
2.创建应用
(1)项目创建完成后需要有具体的应用
(2)创建后生成目录:
admin.py: 模型注册和后台管理相关的文件;
init.py: 应用应该被看做一个Python包;
migrations: 用来放置应用模型的迁移脚本文件;
models.py: 定义模型;
test.py: 放置项目的测试文件;
viems.py: 定义视图;
(3)添加应用
打开settings.py,INSTALLED_APPS下添加:'app01'
3.2配置数据库
在settings.py下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'BookSystem',
'USER':'root',
'PASSWORD':'root',
'HOST':'localhost',
'POST':3306,
}
}
另外django连接mysql需要pymysql包的支持,所以先安装pymysql:
在终端:pip install pymysql
安装完毕,需要导入到django中,打开应用_init_.py文件,加入代码:
import pymysql
pymysql.install_as_MySQLdb() # 与mysql交互的函数
3.3配置模板和静态文件
** 4.相关代码展示**
4.1. urls层
#读者
path("reader/search/", views.reader_search),
path("reader/classify/", views.reader_classify2),
path("reader/<int:nbookclass>/classify/", views.reader_classify),
path("reader/order/", views.reader_order),
path("reader/borrow/",views.reader_borrow),
path("reader/first/", views.reader_first),
path("reader/rule/", views.reader_rule),
path("popular/book/", views.popular_book),
#管理员
#图书管理
path("book/list/",views.book_list),
path("book/add/",views.book_add),
path("book/<int:nid>/edit/",views.book_edit),
path("book/<int:nid>/delete/", views.book_delete),
#用户管理
path("user/list/", views.user_list),
path("user/add/",views.user_add),
path("user/<int:nid>/edit/",views.user_edit),
path("user/<int:nid>/delete/", views.user_delete),
#管理管理员
path("admin/list/", views.admin_list),
path("admin/add/",views.admin_add),
path("admin/<int:nid>/edit/",views.admin_edit),
path("admin/<int:nid>/delete/", views.admin_delete),
#违规
path("rule/list/", views.rule_list),
path("rule/add/",views.rule_add),
path("rule/<int:nid>/edit/",views.rule_edit),
path("rule/<int:nid>/delete/", views.rule_delete),
#登录
path("login/",views.login),
path("log/", views.log)
4.2.models层
class reader(models.Model):
""""读者表"""
reader_id=models.IntegerField(verbose_name="学号")
password=models.CharField(verbose_name="密码",max_length=20)
name=models.CharField(verbose_name="读者姓名",max_length=10)
telephone=models.CharField(verbose_name="联系电话",max_length=15)
email=models.CharField(verbose_name="邮箱地址",max_length=30)
dept=models.CharField(verbose_name="所在院系",max_length=20)
right=models.IntegerField(verbose_name="借阅权限(0或1)")
class book(models.Model):
""""图书表"""
bookname=models.CharField(verbose_name="书籍名称",max_length=20)
author=models.CharField(verbose_name="书籍作者",max_length=20)
pubdate=models.DateField(verbose_name="出版日期")
publish=models.CharField(verbose_name="出版社",max_length=30)
price = models.DecimalField(verbose_name="价格", max_digits=7, decimal_places=2, default=0)
ISBN=models.CharField(verbose_name="书籍ISBN码",max_length=17)
bookclass_choices=(
(1,"哲学、宗教"),
(2,"社会科学总论"),
(3,"政治、法律"),
(4,"军事"),
(5,"经济"),
)
bookclass=models.IntegerField(verbose_name="学科类型",choices=bookclass_choices)
total=models.IntegerField(verbose_name="总量")
margin=models.IntegerField(verbose_name="余量")
booktype_choices=(
(1,"图书"),
(2,"期刊")
)
booktype=models.IntegerField(verbose_name="藏书类型",choices=booktype_choices)
class admin(models.Model):
""""管理员用户表"""
usernum=models.CharField(verbose_name="管理员账号",max_length=20)
password=models.CharField(verbose_name="账号密码",max_length=11)
username=models.CharField(verbose_name="管理员姓名",max_length=10)
class borrow(models.Model):
""""借阅表"""
readerid=models.IntegerField(verbose_name="读者编号")
bookid=models.IntegerField(verbose_name="图书编号")
borrowdate=models.DateField(verbose_name="出借日期")
due=models.DateField(verbose_name="应还日期")
class preconcert(models.Model):
""""预约表"""
readerid = models.IntegerField(verbose_name="读者编号")
bookid = models.IntegerField(verbose_name="图书编号")
predate = models.DateField(verbose_name="预约日期")
class break_rule(models.Model):
""""违规表"""
readerid=models.IntegerField(verbose_name="读者编号")
bookid=models.IntegerField(verbose_name="图书编号")
overdue_choices = (
(0, "无"),
(1, "逾期")
)
overdue=models.IntegerField(verbose_name="逾期(0/1)",choices=overdue_choices)
destory_choices = (
(0, "无"),
(1, "损坏")
)
destory=models.IntegerField(verbose_name="破坏书籍(0/1)",choices=destory_choices)
4.3.views层
# ###############################管理员###################################
#管理图书
def book_list(request):
b = models.book.objects.all()
return render(request, 'book_list.html', {'b': b})
class BookAdd(forms.ModelForm):
class Meta:
model=models.book
fields=["bookname","author","pubdate","publish","ISBN","price","bookclass","total","margin","booktype"]
# widgets={
# "bookname":forms.TextInput(attrs={"class":"form-control"})
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class=“form——control”
for name, field in self.fields.items():
# if name=="password":
# continue
field.widget.attrs = {"class": "form-control"}
def book_add(request):
if request.method == "GET":
bookadd = BookAdd()
return render(request, 'book_add.html', {'bookadd': bookadd})
#用户POST提交数据,数据校验
bookadd=BookAdd(data=request.POST)
if bookadd.is_valid():
#如果数据合法,保存到数据库
bookadd.save()
return redirect('/book/list/')
#校验失败
return render(request, 'book_add.html', {'bookadd': bookadd})
def book_edit(request,nid):
""""编辑书籍"""
row_object = models.book.objects.filter(id=nid).first()
if request.method == "GET":
# 根据id去数据库获取要编辑的那一行数据
bookadd = BookAdd(instance=row_object)
return render(request, "book_edit.html", {'bookadd': bookadd})
bookadd=BookAdd(data=request.POST,instance=row_object)
if bookadd.is_valid():
# 如果数据合法,保存到数据库
bookadd.save()
return redirect('/book/list/')
return render(request, "book_edit.html", {'bookadd': bookadd})
def book_delete(request,nid):
""""删除图书"""
models.book.objects.filter(id=nid).delete()
return redirect('/book/list/')
#管理用户
def user_list(request):
b = models.reader.objects.all()
return render(request, 'user_list.html', {'b': b})
class User(forms.ModelForm):
class Meta:
model=models.reader
fields=["reader_id","password","name","telephone","email","dept","right"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class=“form——control”
for name, field in self.fields.items():
# if name=="password":
# continue
field.widget.attrs = {"class": "form-control"}
def user_add(request):
if request.method == "GET":
user=User()
return render(request, 'user_add.html', {'user': user})
#用户POST提交数据,数据校验
user=User(data=request.POST)
if user.is_valid():
#如果数据合法,保存到数据库
user.save()
return redirect('/user/list/')
#校验失败
return render(request, 'user_add.html', {'user': user})
def user_edit(request,nid):
""""编辑用户"""
row_object = models.reader.objects.filter(id=nid).first()
if request.method == "GET":
# 根据id去数据库获取要编辑的那一行数据
user = User(instance=row_object)
return render(request, "user_edit.html", {'user': user})
user=User(data=request.POST,instance=row_object)
if user.is_valid():
# 如果数据合法,保存到数据库
user.save()
return redirect('/user/list/')
return render(request, "user_edit.html", {'user': user})
def user_delete(request,nid):
""""删除用户"""
models.reader.objects.filter(id=nid).delete()
return redirect('/user/list/')
#管理管理员
def admin_list(request):
b = models.admin.objects.all()
return render(request, 'admin_list.html', {'b': b})
class Admin(forms.ModelForm):
class Meta:
model=models.admin
fields=["usernum","password","username"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class=“form——control”
for name, field in self.fields.items():
# if name=="password":
# continue
field.widget.attrs = {"class": "form-control"}
def admin_add(request):
if request.method == "GET":
admin=Admin()
return render(request, 'admin_add.html', {'admin': admin})
#用户POST提交数据,数据校验
admin=Admin(data=request.POST)
if admin.is_valid():
#如果数据合法,保存到数据库
admin.save()
return redirect('/admin/list/')
#校验失败
return render(request, 'admin_add.html', {'admin': admin})
def admin_edit(request,nid):
""""编辑管理员"""
row_object = models.admin.objects.filter(id=nid).first()
if request.method == "GET":
# 根据id去数据库获取要编辑的那一行数据
admin =Admin(instance=row_object)
return render(request, "admin_edit.html", {'admin': admin})
admin=Admin(data=request.POST,instance=row_object)
if admin.is_valid():
# 如果数据合法,保存到数据库
admin.save()
return redirect('/admin/list/')
return render(request, "admin_edit.html", {'admin': admin})
def admin_delete(request,nid):
""""删除管理员"""
models.admin.objects.filter(id=nid).delete()
return redirect('/admin/list/')
#违规
def rule_list(request):
b = models.break_rule.objects.all()
return render(request, 'rule_list.html', {'b': b})
class Rule(forms.ModelForm):
class Meta:
model=models.break_rule
fields=["readerid","bookid","overdue","destory"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class=“form——control”
for name, field in self.fields.items():
# if name=="password":
# continue
field.widget.attrs = {"class": "form-control"}
def rule_add(request):
if request.method == "GET":
rule=Rule()
return render(request, 'rule_add.html', {'rule': rule})
#用户POST提交数据,数据校验
rule=Rule(data=request.POST)
if rule.is_valid():
#如果数据合法,保存到数据库
rule.save()
return redirect('/rule/list/')
#校验失败
return render(request, 'rule_add.html', {'rule': rule})
def rule_edit(request,nid):
""""编辑管理员"""
row_object = models.break_rule.objects.filter(id=nid).first()
if request.method == "GET":
# 根据id去数据库获取要编辑的那一行数据
rule=Rule(instance=row_object)
return render(request, "rule_edit.html", {'rule': rule})
rule=Rule(data=request.POST,instance=row_object)
if rule.is_valid():
# 如果数据合法,保存到数据库
rule.save()
return redirect('/rule/list/')
return render(request, "rule_edit.html", {'rule': rule})
def rule_delete(request,nid):
""""删除管理员"""
models.break_rule.objects.filter(id=nid).delete()
return redirect('/rule/list/')
# ###############################登录#############################################
""""用户登录"""
class LoginForm(forms.Form):
reader_id=forms.CharField(
label="学号",
widget=forms.TextInput,
required=True
)
password=forms.CharField(
label="密码",
widget=forms.PasswordInput,
required=True
)
def clean_password(self):
password = self.cleaned_data.get("password")
return md5(password)
def login(request):
if request.method=="GET":
form = LoginForm()
return render(request, 'login.html', {'form': form})
form=LoginForm(data=request.POST)
if form.is_valid():
#去数据库校验用户名和密码是否正确,获取用户对象
admin_object=models.reader.objects.filter(reader_id=request.POST.get('reader_id'),password=request.POST.get('password')).first()
if not admin_object:
form.add_error("password","用户名或密码错误!")
return render(request,'login.html',{'form':form})
#网站生成随机字符串
request.session["info"]={'reader_id':admin_object.reader_id,'password':admin_object.password}
return redirect('/reader/first/')
return render(request,'login.html',{'form':form})
"""""管理员登录"""
class LogForm(forms.Form):
usernum=forms.CharField(
label="管理员账号",
widget=forms.TextInput,
required=True
)
password=forms.CharField(
label="密码",
widget=forms.PasswordInput,
required=True
)
def clean_password(self):
password = self.cleaned_data.get("password")
return md5(password)
def log(request):
if request.method=="GET":
form = LogForm()
return render(request, 'log.html', {'form': form})
form=LogForm(data=request.POST)
if form.is_valid():
#去数据库校验用户名和密码是否正确,获取用户对象
admin_object=models.admin.objects.filter(usernum=request.POST.get('usernum'),password=request.POST.get('password')).first()
if not admin_object:
form.add_error("password","用户名或密码错误!")
return render(request,'log.html',{'form':form})
#网站生成随机字符串
request.session["info"]={'usernum':admin_object.usernum,'password':admin_object.password}
return redirect('/book/list/')
return render(request,'log.html',{'form':form})
版权归原作者 大晴的上分之旅 所有, 如有侵权,请联系我们删除。