Django——图书管理系统

一、前期准备

1、创建好 Django 项目

2、准备好数据库 —— 创建数据库:book_system

3、配置项目中的数据库引擎

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql',

'NAME': 'book_system',

'HOST': '127.0.0.1',

'USER': 'root',

'PASSWORD': 'root'

}

}

4、配置静态文件的搜索路径 , 以及在项目的根目录中创建一个 static 存放静态文件数据文件夹

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

5、导入 html 模板文件和静态文件数据。

二、用户注册

1、响应用户注册页面的视图

# 路由

# 用户注册视图路由

path('register/' , views.RegisterView.as_view()),

# 响应视图

class RegisterView(View):

'''

用户注册页面视图

'''

def get(self , request):

# 响应注册页面

return render(request , 'register.html')

2、定义用户数据模型类 , 保存用户注册的个人数据信息

class User(models.Model):

'''

保存用户注册数据

'''

username = models.CharField(max_length=20)

password = models.IntegerField()

email = models.EmailField()

3、设置后端对用户注册数据进行验证 , 在对应的应用下创建一个 forms 的模块 , 实现数据验证

class RegisterForm(forms.Form):

'''

验证用户注册数据

'''

username = forms.CharField(min_length=3 , max_length=15,

error_messages={

'min_length':'用户名长度不足',

'max_length':'用户名长度超出',

'required':'用户名不允许为空',

})

password = forms.CharField(min_length=6 , max_length=15,

error_messages={

'min_length':'密码长度不足',

'max_length':'密码长度超出',

'required':'密码不允许为空',

})

resetpw = forms.CharField(min_length=6 , max_length=15,

error_messages={

'min_length':'密码长度不足',

'max_length':'密码长度超出',

'required':'密码不允许为空',

})

email = forms.EmailField(error_messages={'invalid':'邮箱格式不正确',

'required':'邮箱不允许为空'})

def clean(self):

pwd1 = self.cleaned_data.get('password')

pwd2 = self.cleaned_data.get('resetpw')

if pwd1 != pwd2:

self.add_error('resetpw' , '两次密码输入不一致')

return self.cleaned_data

def clean_username(self):

name = self.cleaned_data.get('username')

if not re.match(r'^[a-zA-Z0-9_]{3,15}$' , name):

self.add_error('username' , '用户名格式不正确')

return name

4、在注册视图中接收用户注册传递的数据 , 进行数据验证

class RegisterView(View):

'''

用户注册页面视图

'''

def get(self , request):

# 响应注册页面

return render(request , 'register.html')

def post(self , request):

# 接收用户注册输入的数据

# 传递给 forms 组件进行数据验证

register_form = RegisterForm(request.POST)

# 判断 forms 组件是否返回异常信息

if register_form.is_valid():

# 说明数据合法 没有异常 , 将用户数据保存到数据库中

# 用户数据要从 forms 组件中取

username = register_form.cleaned_data.get('username')

password = register_form.cleaned_data.get('password')

email = register_form.cleaned_data.get('email')

return HttpResponse('用户数据正常')

else:

# 用户数据不合法 , 将异常信息返回到前端页面中

return render(request , 'register.html' , locals())

当用户数据异常不合法的情况下 ,后端将异常请求返回到前端 。在 html 页面中获取后端的异常数据信息

用户名:

{{ register_form.username.errors.0 }}

5、实现图片验证码 , 进行验证用户输入的验证码 ,验证码正确数据保存到数据库中,注册成功;否则用户注册失败。

实现图片验证码的代码,直接使用之前写的。

在当前应用下创建包 —— ImageCode

实现验证码的视图

# 路由

# 图片验证码

path('image_code/' , views.CodeImg),

# 视图

def CodeImg(request):

# 响应图片验证码视图

# 获取图片验证码以及验证码数据

image , text = create_img()

# session 会话

# 将验证码数据保存到 session 会话中 , 以键值对的方式保存

request.session['code'] = text

# 将图片响应到出现

return HttpResponse(image , content_type='image/png')

在注册是模板中添加验证码的文本框

验证码:

sqlite 数据库 Django项目之图书管理系统  第1张

6、前端数据校验 , 使用 vue 的框架进行数据校验

在标签中绑定数据信息 ,以及对文本框绑定对应的方法

用户名:

required v-model="username" @blur="check_name">

{{ register_form.username.errors.0 }}

校验用户名是否重复的视图

# 路由

# 检验用户名是否重复

re_path('count/(?P[a-zA-Z0-9_ ]{3,15})/' , views.username_count),

# 视图

def username_count(request , username):

# 从数据库获取用户数据

count = User.objects.filter(username=username).count()

return JsonResponse({'code':200 , 'errmsg':"OK" , 'count':count})

在静态文件中创建 register.js 文件

let vm = new Vue({

el:'#app',

delimiters: ['[[' , ']]'],

data:{

username:'',

password:'',

resetpw:'',

image_code_url:'',

error_name:false,

error_password:false,

error_resetpw:false,

error_name_message:'',

},

// 这个方法在 html 页面执行的时候 , 会被自动调用

mounted(){

this.image_code();

},

methods:{

// 生成图片验证码

image_code(){

// 短时间内路由一致的情况下,会无法响应成功

// 添加时间参数,保证在短时间内请求的路由不一致

this.image_code_url = '/image_code/?'+ new Date().getTime()

},

// 验证用户名

check_name(){

// 定义用户名的规则范围

let re = /^[a-zA-Z0-9_]{3,15}$/;

// 判断用户名是否满足定义的规则

if(re.test(this.username)){

// 用户名合法

this.error_name = false;

} else {

// 用户名不合法

this.error_name = true;

this.error_name_message = '用户名不合法';

}

// 判断用户名是否重复

// 前提保证用户名合法

if(this.error_name == false){

// 发送 ajax 请求

axios.get(

'/count/'+this.username+'/',

{responseType:'json'}

)

// 请求成功

.then(response => {

if(response.data.count > 0){

// 用户已存在

this.error_name = true;

this.error_name_message = '用户名已存在';

} else {

this.error_name = false;

}

})

// 请求失败

.catch(error => {

console.log(error.response)

})

}

},

// 校验密码

check_password(){

let re = /^[a-zA-Z0-9_]{6,15}$/;

if(re.test(this.password)){

// 密码字符合法

this.error_password = false;

} else {

// 密码字符不合法

this.error_password = true;

}

},

// 校验两次密码是否一致

check_resetpw(){

if(this.password == this.resetpw){

this.error_resetpw = false;

} else {

this.error_resetpw = true;

}

},

// 表单是否允许提交的方法

on_submit(){

// 调用所有绑定的方法

this.check_name();

this.check_password();

this.check_resetpw();

// 判断 error 对应的值是否为 true , 如果其中有一个为 true 则不允许提交

if(this.error_name == true || this.error_password == true || this.error_resetpw == true){

// 数据问题 , 禁止表单提交

window.event.returnValue = false;

}

}

}

})

修改 图片验证码的 html 标签

验证码:

sqlite 数据库 Django项目之图书管理系统  第2张

7、在注册视图中 , 实现图片验证码的校验 , 验证码校验正确,用户数据保存到数据库中,用户注册成功;否则注册失败。

class RegisterView(View):

'''

用户注册页面视图

'''

def get(self , request):

# 响应注册页面

return render(request , 'register.html')

def post(self , request):

# 接收用户注册输入的数据

# 传递给 forms 组件进行数据验证

register_form = RegisterForm(request.POST)

# 判断 forms 组件是否返回异常信息

if register_form.is_valid():

# 说明数据合法 没有异常 , 将用户数据保存到数据库中

# 用户数据要从 forms 组件中取

username = register_form.cleaned_data.get('username')

password = register_form.cleaned_data.get('password')

email = register_form.cleaned_data.get('email')

# 校验验证码 , 获取用户数输入的验证码

img_code = request.POST.get('img_code')

# 从 session 会话中获取保存的验证码

code = request.session['code']

if img_code == code:

# 验证码正确 , 将用户拒数据保存到数据库中,用户注册成功

User.objects.create(username=username , password=password , email=email)

# 注册成功重定向首页

return redirect('/index/')

else:

# 验证码错误

return render(request , 'register.html' , {'code_error':'验证码错误'})

else:

# 用户数据不合法 , 将异常信息返回到前端页面中

return render(request , 'register.html' , locals())

8、实现首页

# 网站首页

path('index/' , views.index),

def index(request):

# 响应首页

return render(request , 'index.html')

三、用户登录

响应登录页面数据 , 接收用户登录的数据。

# 用户登录

path('login/' , views.LoginView.as_view()),

class LoginView(View):

'''

用户登录视图

'''

def get(self , request):

return render(request , 'login.html')

def post(self , request):

# 校验用户输入的数据

login_form = LoginForm(request.POST)

if login_form.is_valid():

username = login_form.cleaned_data.get('username')

password = login_form.cleaned_data.get('password')

# 到数据库中进行查询用户数据是否存在

user = User.objects.filter(username=username , password=password)

if user:

# 用户登录成功

return redirect('/index/')

else:

return render(request, 'login.html', {'errormsg': '账号或者密码错误'})

else:

return render(request , 'login.html' , {'errormsg':'账号或者密码错误'})

四、出版社信息

1、 定义出版社模型类

class PublishingHouse(models.Model):

'''

出版社信息模型类

'''

# 出版社名称

name = models.CharField(max_length=20)

# 出版社类型

publisher_type = models.CharField(max_length=15)

# 出版社成立时间

create_time = models.DateField()

# 出版社位置

address = models.CharField(max_length=30)

2、设置出版社模板页面

{% block main%}

{% for foo in publisher %}

{% endfor %}

序号出版社名称出版社类型出版社成立时间出版社地址操作
{{ foo.id }}{{ foo.name }}{{ foo.publisher_type }}{{ foo.create_time }}{{ foo.address }}

修改

删除

{% endblock %}

3、 响应视图

# 出版社列表响应

path('publisher_list/' , views.publisher_list),

# 视图

def publisher_list(request):

# 响应出版社列表

# 从数据库中获取出版社的所有信息

publisher = PublishingHouse.objects.all()

return render(request , 'publisher_list.html' , locals())

4、添加出版社信息操作

实现添加数据的模板页面

{% block main%}

{% csrf_token %}

出版社名称

出版社类型

出版社成立时间

出版社地址

{% endblock main %}

# 添加出版社数据

path('add_publisher/' , views.AddPublisher.as_view()),

# 视图

class AddPublisher(View):

'''

添加出版社数据视图

'''

def get(self , request):

return render(request , 'add_publisher.html')

def post(self , request):

name = request.POST.get('name')

publisher_type = request.POST.get('publisher_type')

create_time = request.POST.get('create_time')

address = request.POST.get('address')

# 将数据保存到数据库中

PublishingHouse.objects.create(

name=name,

publisher_type=publisher_type,

create_time=create_time,

address=address

)

# 数据保存成功 , 重定向到列表页

return redirect('/publisher_list/')

5、修改出版社信息

获取要修改的出版社信息 , 要知道是哪个出版社信息需要修改

获取要修改的出版社信息 , 响应到页面中。

重新接收用户修改好的出版社数据保存到数据库中。

实现修改数据模板页

{% block main %}

{% csrf_token %}

出版社名称

出版社类型

出版社成立时间

出版社地址

{% endblock main %}

# 路由

# 修改出版社信息

path('edit_publisher/' , views.EditPublisher.as_view()),

# 视图

class EditPublisher(View):

'''

修改出版社信息的视图

'''

def get(self , request):

# 获取用户要修改的出版社信息

id = request.GET.get('id')

edit = PublishingHouse.objects.get(id=id)

return render(request , 'edit_publisher.html' , locals())

def post(self , request):

id = request.GET.get('id')

name = request.POST.get('name')

publisher_type = request.POST.get('publisher_type')

create_time = request.POST.get('create_time')

address = request.POST.get('address')

edit_data = PublishingHouse.objects.filter(id=id)

edit_data.update(

name=name,

publisher_type=publisher_type,

create_time=create_time,

address=address

)

return redirect('/publisher_list/')

6、删除出版社信息

# 路由

# 删除出版社信息

path('del_publisher/' , views.del_publisher),

# 视图

def del_publisher(request):

# 获取要删除的出版社信息:id

id = request.GET.get('id')

PublishingHouse.objects.filter(id=id).delete()

return redirect('/publisher_list/')

五、图书信息

1、图书模型类

class Book(models.Model):

'''

图书信息模型类

'''

name = models.CharField(max_length=20)

carrier = models.CharField(max_length=10)

number_of_words = models.IntegerField()

publisher_time = models.DateField()

book_image = models.CharField(max_length=20)

book_intro = models.CharField(max_length=300)

price = models.DecimalField(max_digits=5 , decimal_places=2)

inventory = models.IntegerField()

publisher = models.ForeignKey(to='PublishingHouse' , on_delete=models.CASCADE)

2、图书列表页

{% block main %}

{% for foo in book %}

{% endfor %}

序号图书名称图书价格库存查询详情操作
{{ foo.id }}{{ foo.name }}{{ foo.price }}{{ foo.inventory }}查看

修改

删除

{% endblock main %}

# 查看图书列表页

path('book_list/' , views.book_list),

def book_list(request):

book = Book.objects.all()

return render(request , 'book_list.html' , locals())

3、添加图书数据

{% block main%}

{% csrf_token %}

图书名称

图书载体

图书字数

图书发表时间

图书图片

图书简介

图书价格

图书库存

出版社

{% endblock main %}

# 添加图书信息

path('add_book/' , views.AddBook.as_view()),

class AddBook(View):

'''

添加图书信息

'''

def get(self , request):

# 获取出版社数据

publisher = PublishingHouse.objects.all()

return render(request , 'add_book.html' , locals())

def post(self , request):

name = request.POST.get('name')

carrier = request.POST.get('carrier')

number = request.POST.get('number')

time = request.POST.get('time')

book_image = request.FILES.get('book_image')

book_intro = request.POST.get('book_intro')

price = request.POST.get('price')

inventory = request.POST.get('inventory')

publisher_id = request.POST.get('publisher_id')

# 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片

if book_image:

# 获取文件名

book_image_name = book_image.name

# 将图片保存到指定位置

image_dir = os.path.join(STATICFILES_DIRS[0] , 'book_image' , book_image_name)

with open(image_dir , 'wb') as f:

for i in book_image:

f.write(i)

else:

book_image = '暂无.jpg'

if not book_intro:

book_intro = '暂无作品介绍,正在整理中……'

Book.objects.create(

name=name,

carrier=carrier,

number_of_words=number,

publisher_time=time,

book_image=book_image,

book_intro=book_intro,

price=price,

inventory=inventory,

publisher_id=publisher_id

)

return redirect('/book_list/')

4、查看图书详情

{% block main %}

图书名称:{{ book.name }}

图书作者:

图书简介{{ book.book_intro }}图书图片sqlite 数据库 Django项目之图书管理系统  第3张
文学载体{{ book.carrier }}图书字数{{ book.number_of_words }}
发表时间{{ book.publisher_time }}图书出版社{{ book.publisher.name }}

{% endblock main %}

# 查看图书详情

path('check_book/' , views.book_particulars),

def book_particulars(request):

id = request.GET.get('id')

book = Book.objects.get(id=id)

return render(request , 'book_particulars.html' , locals())

5、删除图书信息

def del_book(request):

id = request.GET.get('id')

Book.objects.filter(id=id).delete()

return redirect('/book_list/')

6、修改图书信息

class EditBook(View):

def get(self , request):

id = request.GET.get('id')

book = Book.objects.get(id=id)

publisher = PublishingHouse.objects.all()

return render(request , 'edit_book.html' , locals())

def post(self , request):

id = request.GET.get('id')

name = request.POST.get('name')

carrier = request.POST.get('carrier')

number = request.POST.get('number')

time = request.POST.get('time')

book_image = request.FILES.get('book_image')

book_intro = request.POST.get('book_intro')

price = request.POST.get('price')

inventory = request.POST.get('inventory')

publisher_id = request.POST.get('publisher_id')

# 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片

if book_image:

# 获取文件名

book_image_name = book_image.name

# 将图片保存到指定位置

image_dir = os.path.join(STATICFILES_DIRS[0], 'book_image', book_image_name)

with open(image_dir, 'wb') as f:

for i in book_image:

f.write(i)

else:

book_image = '暂无.jpg'

if not book_intro:

book_intro = '暂无作品介绍,正在整理中……'

edit_data = Book.objects.filter(id=id)

edit_data.update(

name=name,

carrier=carrier,

number_of_words=number,

publisher_time=time,

book_image=book_image,

book_intro=book_intro,

price=price,

inventory=inventory,

publisher_id=publisher_id

)

return redirect('/book_list/')

{% block main%}

{% csrf_token %}

图书名称

图书载体

图书字数

图书发表时间

图书图片

图书简介

图书价格

图书库存

出版社

{% endblock main %}

六、作者信息

1、作者模型类

class Author(models.Model):

'''

作者信息

'''

# 作者姓名

name = models.CharField(max_length=15)

# 作者照片

author_picture_name = models.CharField(max_length=20)

# 作者简介

author_intro = models.CharField(max_length=150)

# 作者图书

book = models.ManyToManyField(to='Book')

2、作者列表页响应

{% block main %}

{% for foo in author %}

{% endfor %}

序号作者名称作者详情操作
{{ foo.id }}{{ foo.name }}查看

修改

删除

{% endblock main %}

def author_list(request):

author = Author.objects.all()

return render(request , 'author_list.html' , locals())

3、添加作者信息

{% block main%}

{% csrf_token %}

作者名称

作者图片

作者简介

作者作品

{% for foo in book %}

{{ foo.name }}

{% endfor %}

{% endblock main %}

class AddAuthor(View):

def get(self , request):

book = Book.objects.all()

return render(request , 'add_author.html' , locals())

def post(self , request):

name = request.POST.get('name')

author_intro = request.POST.get('author_intro')

author_image = request.FILES.get('author_image')

# 前端中的多选框 , 接受的是一个列表类型的数据

# getlist 的方式接受

books = request.POST.getlist('books')

# 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片

if author_image:

# 获取文件名

author_image_name = author_image.name

# 将图片保存到指定位置

image_dir = os.path.join(STATICFILES_DIRS[0], 'author_image', author_image_name)

with open(image_dir, 'wb') as f:

for i in author_image:

f.write(i)

else:

author_image = '暂无.jpg'

if not author_intro:

author_intro = '暂无作者介绍,正在整理中……'

author = Author.objects.create(

name=name,

author_picture_name=author_image,

author_intro=author_intro)

author.book.set(books)

return redirect('/author_list/')

4、查看作者详情数据

def check_author(request):

id = request.GET.get('id')

author = Author.objects.get(id=id)

book = Book.objects.filter(author__id=id)

return render(request , 'check_author.html' , locals())

{% block main %}

作者:{{ author.name }}

作者简介{{ author.author_intro }}作者图片sqlite 数据库 Django项目之图书管理系统  第4张

{% for foo in book %}

{% endfor %}

作品
{{ foo.name }}

{% endblock main %}

5、修改作者信息

{% block main%}

{% csrf_token %}

作者名称

作者图片

作者简介

作者作品

{% for foo in book %}

{{ foo.name }}

{% endfor %}

{% endblock main %}

class EditAuthor(View):

def get(self , request):

id = request.GET.get('id')

author = Author.objects.get(id=id)

book = Book.objects.all()

return render(request , 'edit_author.html' , locals())

def post(self , request):

id = request.GET.get('id')

name = request.POST.get('name')

author_intro = request.POST.get('author_intro')

author_image = request.FILES.get('author_image')

# 前端中的多选框 , 接受的是一个列表类型的数据

# getlist 的方式接受

books = request.POST.getlist('books')

# 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片

if author_image:

# 获取文件名

author_image_name = author_image.name

# 将图片保存到指定位置

image_dir = os.path.join(STATICFILES_DIRS[0], 'author_image', author_image_name)

with open(image_dir, 'wb') as f:

for i in author_image:

f.write(i)

else:

author_image = '暂无.jpg'

if not author_intro:

author_intro = '暂无作者介绍,正在整理中……'

edit_data = Author.objects.get(id=id)

edit_data.name = name

edit_data.author_intro = author_intro

edit_data.author_picture_name = author_image

edit_data.book.set(books)

edit_data.save()

return redirect('/author_list/')

6、删除作者

def del_author(request):

id = request.GET.get('id')

Author.objects.filter(id=id).delete()

return redirect('/author_list/')

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: