图书管理系统项目
图书管理系统
项目实操
本项目的数据库>>>:djangodb3
表数据
我们使用的是auth_user注册器,校验用户是否登录,我们可以不用写装饰器,直接导入模块的装饰器使用。
- 直接引入模块login_required
from django.contrib.auth.decorators import login_required
eg:
# 用户的基本信息
@login_required
def info_func(request):
return render(request, 'infoPage.html', locals())
- 在settings中配置一下路径
模型层
models.py
from django.db import models
# Create your models here.
class Book(models.Model):
"""图书详情"""
title = models.CharField(max_length=32, verbose_name='书名')
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
publish_date = models.DateTimeField(auto_now_add=True, verbose_name='出版日期')
# 书与出版社 一对多
publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)
# 书与作者 多对多
authors = models.ManyToManyField(to='Author')
def __str__(self):
return f'书籍对象:{self.title}'
class Publish(models.Model):
""" 出版社详情"""
name = models.CharField(max_length=32, verbose_name='出版社名')
address = models.CharField(max_length=64, verbose_name='地址')
def __str__(self):
return f'出版对象:{self.name}'
class Author(models.Model):
""" 作者"""
name = models.CharField(max_length=32, verbose_name='作者名')
age = models.IntegerField(verbose_name='年龄')
# 作者与作者详情 一对一
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.SET_NULL, null=True)
def __str__(self):
return f'作者对象:{self.name}'
class AuthorDetail(models.Model):
""" 作者详情"""
phone = models.BigIntegerField(verbose_name='号码')
address = models.CharField(max_length=64, verbose_name='作者地址')
def __str__(self):
return f'作者详情:{self.phone}'
路由层
urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 首页展示(也可以考虑使用路由分发)
path('home/', views.home_func, name='home_view'),
# 用户注册
path('register/', views.register_func, name='register_view'),
# 用户登录
path('login/', views.login_func, name='login_views'),
# 用户的基本数据信息
path('info/', views.info_func, name='info_view'),
# 用户修改密码
path('set_pwd/',views.set_pwd_func,name='set_pwd'),
# 用户退出登录
path('logout/',views.logout_func,name='logout_views'),
# 图书列表展示页
path('book_list/', views.book_list_func, name='book_list'),
# 图书添加页
path('book_add/', views.book_add_func, name='book_add'),
# 图书编辑页
path('book_edit/<int:book_pk>/', views.book_edit_func, name='book_edit'), # book_edit_func(request,book_pk='
path('book_delete/<int:book_pk>/', views.book_delete_func, name='book_delete'),
# 出版社列表
path('publish_list/',views.publish_list_func,name='publish_list'),
# 出版社添加页
path('publish_add/',views.publish_add_list,name='publish_add'),
# 出版社编辑页
path('publish_edit/<int:publish_pk>/',views.publish_edit_func,name='publish_edit'),
# 出版社删除页
path('publish_delete/<int:publish_pk>/',views.publish_delete_func,name='publish_delete'),
# 作者列表
path('author_list/',views.author_list_func,name='author_list'),
# 作者添加
path('author_add/',views.author_add_func,name='author_add'),
# 作者编辑
path('author_edit/<int:author_pk>/',views.author_edit_func,name='author_edit'),
# 作者删除
path('author_delete/<int:author_pk>/',views.author_delete_func,name='author_delete'),
]
视图层
views.py
from django.shortcuts import render, HttpResponse, redirect
from app01 import models
# Create your views here.
def home_func(request):
return render(request, 'home.html')
# 用户注册 auth模块
from django.contrib import auth
from django.contrib.auth.models import User
def register_func(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
print(username, password)
# 校验用户名是否已经存在
res = User.objects.filter(username=username)
print(res)
if res:
return HttpResponse('用户名已经存在')
User.objects.create_user(username=username, password=password)
return render(request, 'loginPage.html')
return render(request, 'registerPage.html')
# 用户登录
def login_func(request):
# if request.method=='GET':
# target_path=request.GET.get('next'):
# if target_path:
# return render(target_path)
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = auth.authenticate(request, username=username, password=password)
if user_obj:
auth.login(request, user_obj)
return render(request, 'home.html')
return HttpResponse('用户名或者密码不正确')
return render(request, 'loginPage.html', locals())
from django.contrib.auth.decorators import login_required
# 校验用户是否登录
# 用户的基本信息
@login_required
def info_func(request):
return render(request, 'infoPage.html', locals())
# 用户修改密码
@login_required
def set_pwd_func(request):
if request.method == 'POST':
password = request.POST.get('password')
new_password = request.POST.get('new_password')
confirm_password = request.POST.get('confirm_password')
# 1.判断二次密码是否正确
if new_password != confirm_password:
return HttpResponse('两次密码不一致')
# 2.判断原密码是否正确
is_right = request.user.check_password(password)
if not is_right:
return HttpResponse('原密码错误')
# 3.修改密码
request.user.set_password(new_password)
request.user.save() # 一定要保存
return redirect('/login/') # 两个账户在这里折在这里了
# return render(request,'loginPage.html')
return render(request, 'setPwdPage.html', locals())
# 退出登录
def logout_func(request):
auth.logout(request)
return redirect('/home/')
# 图书列表展示
@login_required # 校验用户是否登录
def book_list_func(request):
# 1.展示所有的图书数据
book_queryset = models.Book.objects.all() # queryset[数据对象,数据对象]
# 2.返回一个html页面并在页面上展示图书信息
return render(request, 'bookListPag.html', locals())
# 图书添加
def book_add_func(request):
# 3.数据添加
print(request.POST)
if request.method == 'POST':
title = request.POST.get('title') # 获取列表最后一个数据值
price = request.POST.get('price') # 获取列表最后一个数据值
publish_date = request.POST.get('publish_date') # 获取列表最后一个数据值
publish_id = request.POST.get('publish_id') # 获取列表最后一个数据值
author_id_list = request.POST.getlist('author_id_list') # 获取完整的列表数据
# TODO: 一些小判断未做
book_obj = models.Book.objects.create(title=title, price=price, publish_date=publish_date,
publish_id=publish_id)
book_obj.authors.add(*author_id_list) # add(1,2,3)
# 重定向到展示页
return redirect('book_list') # 只支持没有动态匹配的方向解析
# 2.分析可得页面需要出版社和作者的全部信息
publish_queryset = models.Publish.objects.all()
author_queryset = models.Author.objects.all()
# 1.返回一个让用户输入添加书籍相关数据的html的页面
return render(request, 'bookAddPage.html', locals())
# 图书编辑
def book_edit_func(request, book_pk):
# 1.根据匹配到的数据主键值查询数据对象
edit_obj = models.Book.objects.filter(pk=book_pk).first()
# 4.点击书籍编辑按钮,要朝书籍列表发送一个post请求
if request.method == 'POST':
title = request.POST.get('title') # 获取列表最后一个数据值
price = request.POST.get('price') # 获取列表最后一个数据值
publish_date = request.POST.get('publish_date') # 获取列表最后一个数据值
publish_id = request.POST.get('publish_id') # 获取列表最后一个数据值
author_id_list = request.POST.getlist('author_id_list') # 获取完整的列表数据
models.Book.objects.filter(pk=book_pk).update(title=title, price=price, publish_date=publish_date,
publish_id=publish_id)
edit_obj.authors.set(author_id_list)
return redirect('book_list')
# 3.分析可得页面需要出版社和作者的全部信息
publish_queryset = models.Publish.objects.all()
author_queryset = models.Author.objects.all()
# 2.传递给html页面展示给用户看
return render(request, 'bookEditPage.html', locals())
# 图书删除
def book_delete_func(request, book_pk):
# 1.删除书籍数据
# models.Book.objects.filter(pk=book_pk).delete()
# 2.删除本数据及与这本数据相关的绑定关系
delete_book_obj = models.Book.objects.filter(pk=book_pk).first()
delete_book_obj.authors.clear()
models.Book.objects.filter(pk=book_pk).delete()
return redirect('book_list')
# 出版社列表
@login_required
def publish_list_func(request):
# 1.获取所有的出版社对象
publish_queryset = models.Publish.objects.all() # queryset[数据对象,数据对象]
return render(request, 'publishListPage.html', locals())
# 出版社添加
def publish_add_list(request):
if request.method == 'POST':
name = request.POST.get('name')
address = request.POST.get('address')
# 1.判断name和address不能空
if len(name) == 0 or len(address) == 0:
return HttpResponse('名字或者地址不能为空')
# 判断出版社是否添加过
publish_obj = models.Publish.objects.filter(name=name)
if publish_obj:
return HttpResponse('出版社已经存在')
# 2.添加到表中
models.Publish.objects.create(name=name, address=address)
# 3.重定向到展示页
return redirect('/publish_list/')
return render(request, 'publishAddPage.html')
# 出版社编辑
def publish_edit_func(request, publish_pk):
# 1.获取用户想要编辑对象
edit_obj = models.Publish.objects.filter(pk=publish_pk).first()
if request.method == 'POST':
name = request.POST.get('name')
address = request.POST.get('address')
# 1.判断name和address不能空
if len(name) == 0 or len(address) == 0:
return HttpResponse('名字或者地址不能为空')
models.Publish.objects.filter(pk=publish_pk).update(name=name, address=address)
# 2.重定向到展示页
return redirect('/publish_list/')
return render(request, 'publishEditPage.html', locals())
# 出版社删除
def publish_delete_func(request, publish_pk):
# 1.获取用户想要删除的对象
del_obj = models.Publish.objects.filter(pk=publish_pk).first()
# 2.先删除绑定关系表的外键
models.Publish.objects.filter(pk=publish_pk).delete()
return redirect('/publish_list/')
# 作者列表
@login_required
def author_list_func(request):
author_queryset = models.Author.objects.all()
return render(request, 'authorListPage.html', locals())
# 作者添加
def author_add_func(request):
# 2.获取添加的名字和年纪
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
author_phone = request.POST.get('author_phone')
author_address = request.POST.get('author_address')
# 3.判断name和age不能空
if len(name) == 0 or len(age) == 0:
return HttpResponse('名字、年纪和详情不能为空')
# 4 判断作者是否添加过
author_obj = models.Author.objects.filter(name=name, age=age)
if author_obj:
return HttpResponse('作者已存在')
# 5.先创建作者详情表的对象
author_detail_obj = models.AuthorDetail.objects.create(phone=author_phone, address=author_address)
author_obj = models.Author.objects.create(name=name, age=age, author_detail=author_detail_obj)
# 6.重定向到展示页
return redirect('/author_list/')
# 1.分析可得页面需要将获取详情展示在页面的全部信息
author_detail_queryset = models.AuthorDetail.objects.all()
return render(request, 'authorAddPage.html', locals())
# 作者编辑
def author_edit_func(request, author_pk):
# 1.获取用户想要编辑对象
edit_obj = models.Author.objects.filter(pk=author_pk).first()
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
author_phone = request.POST.get('author_phone')
author_address = request.POST.get('author_address')
# 1.判断name和年龄不能空
if len(name) == 0 or len(age) == 0:
return HttpResponse('名字或者年龄不能为空')
# 5.先更新作者详情表的对象
models.AuthorDetail.objects.filter(author__pk=author_pk).update(phone=author_phone,
address=author_address)
# 再更新作者表
author_obj = models.Author.objects.filter(pk=author_pk).update(name=name, age=age)
# 2.重定向到展示页
return redirect('/author_list/')
# 1.分析可得页面需要将获取详情展示在页面的全部信息
author_detail_queryset = models.AuthorDetail.objects.all()
return render(request, 'authorEditPage.html', locals())
# 作者删除
def author_delete_func(request, author_pk):
# 1.获取用户想要删除的对象
del_obj = models.Author.objects.filter(pk=author_pk).first()
# 2.先删除绑定关系表的外键
models.Author.objects.filter(pk=author_pk).delete()
return redirect('/publish_list/')
静态文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
static文件夹
模板层
删除数据不用做前端展示,只需要做后端逻辑。
home和用户信息表
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/bootstrap-3.4.1-dist/css/bootstrap.min.css'%}">
<script src="{% static 'bootstrap-3.4.1-dist/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
{% block css %}
{% endblock %}
</head>
<body>
{# 导航条#}
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.user.username }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'login_views' %}">登录</a></li>
<li><a href="{% url 'info_view' %}">基本信息</a></li>
<li><a href="{% url 'set_pwd' %}">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="{% url 'logout_views' %}">退出登录</a></li>
</ul>
</li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'register_view' %}">register</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">login <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'login_views' %}">登录</a></li>
<li><a href="{% url 'login_views' %}">基本信息</a></li>
<li><a href="{% url 'login_views' %}">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="{% url 'login_views' %}">退出登录</a></li>
</ul>
</li>
</ul>
{% endif %}
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid"></div>
<div class="row">
<div class="col-md-2">
<div class="list-group">
<a href="{% url 'home_view' %}" class="list-group-item active">
首页展示
</a>
<a href="{% url 'book_list' %}" class="list-group-item">图书列表</a>
<a href="{% url 'publish_list' %}" class="list-group-item">出版社列表</a>
<a href="{% url 'author_list' %}" class="list-group-item">作者列表</a>
<a href="#" class="list-group-item">更多</a>
</div>
<div class="list-group">
<a href="#" class="list-group-item active">
图书功能区
</a>
<a href="#" class="list-group-item">图书列表</a>
<a href="#" class="list-group-item">出版社列表</a>
<a href="#" class="list-group-item">作者列表</a>
<a href="#" class="list-group-item">更多</a>
</div>
<div class="list-group">
<a href="#" class="list-group-item active">
图书功能区
</a>
<a href="#" class="list-group-item">图书列表</a>
<a href="#" class="list-group-item">出版社列表</a>
<a href="#" class="list-group-item">作者列表</a>
<a href="#" class="list-group-item">更多</a>
</div>
</div>
<div class="col-md-10">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">BMS</h3>
</div>
<div class="panel-body">
{% block content %}
<div class="page-header">
<h1>library<small>欢迎进入</small></h1>
<div class="jumbotron">
<h1>图书管理系统<h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
<div class="row">
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2F1113%2F032R0123003%2F20032Q23003-7-1200.jpg&refer=http%3A%2F%2Flmg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1673949896&t=ccb7280c77ed99df0945f970813356b0" alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hippopx.com%2Fphotos%2F509%2F345%2F217%2Fbooks-research-library-shelves-preview.jpg&refer=http%3A%2F%2Fi0.hippopx.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1673949896&t=0776d2a24b9f454b0c791635b46f060d" alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img0.baidu.com/it/u=2604580050,2817040909&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=334" alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img1.baidu.com/it/u=703895032,2344231475&fm=253&fmt=auto&app=138&f=JPEG?w=639&h=500" alt="...">
</a>
</div>
...
</div>
</div>
{% endblock %}
</div>
</div>
</div>
</div>
{% block js %}
{% endblock %}
</body>
</html>
基于auth_user注册表的注册与登录
register.html
{% extends 'home.html' %}
{% block content %}
<h1>注册页面</h1>
<form action="" method="post">
{% csrf_token %}
<p>username:
<input type="text" name="username">
</p>
<p>password:
<input type="text" name="password">
</p>
<p>email:
<input type="email" name="email">
</p>
<input type="submit">
</form>
{% endblock %}
login.html
{% extends 'home.html' %}
{% block content %}
<h1>欢迎来到登录页面</h1>
<form action="" method="post">
{% csrf_token %}
<p>username:
<input type="text" name="username">
</p>
<p>password:
<input type="password" name="password">
</p>
<input type="submit">
</form>
{% endblock %}
是否登录是在总页面修改的,利用了auth_user注册的user模块的request.user.is_authenticated进行判断。
</form>
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.user.username }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'login_views' %}">登录</a></li>
<li><a href="{% url 'info_view' %}">基本信息</a></li>
<li><a href="{% url 'set_pwd' %}">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="{% url 'logout_views' %}">退出登录</a></li>
</ul>
</li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'register_view' %}">register</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">login <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'login_views' %}">登录</a></li>
<li><a href="{% url 'login_views' %}">基本信息</a></li>
<li><a href="{% url 'login_views' %}">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="{% url 'login_views' %}">退出登录</a></li>
</ul>
</li>
</ul>
{% endif %}
infoPage.html(登录个人的信息)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">用户基本信息</h1>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>用户名</th>
<th>邮箱</th>
<th>是否超级管理员</th>
<th>是否激活</th>
<th>注册时间</th>
<th>上次登录</th>
</tr>
</thead>
<tbody>
{# {% for user in request.user %}#}
{# <tr>#}
{# <td>{{ user.id }}</td>#}
{# <td>{{ user.username }}</td>#}
{# <td>{{ user.email }}</td>#}
{# <td>{{ user.is_superuser }}</td>#}
{# <td>{{ user.is_active }}</td>#}
{# <td>{{ user.date_joined|date:'Y:m:d H:i:s' }}</td>#}
{# </tr>#}
{# #}
{# {% endfor %}#}
<tr>
<td>{{ request.user.id }}</td>
<td>{{ request.user.username }}</td>
<td>{{ request.user.email }}</td>
<td>{{ request.user.is_superuser }}</td>
<td>{{ request.user.is_active }}</td>
<td>{{ request.user.date_joined|date:'Y年m月d日 H:i:s' }}</td>
<td>{{ request.user.last_login|date:'Y年m月d日 H:i:s' }}</td>
</tr>
</tbody>
</table>
{% endblock %}
setPwdPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">用户修改密码</h1>
<form action="" method="post" class="text-center">
<p>username:
<input type="text" name="username" value="{{ request.user.username }}">
</p>
<p>password:
<input type="password" name="password" >
</p>
<p>new_password:
<input type="text" name="new_password">
</p>
<p>confirm_password:
<input type="text" name="confirm_password">
</p>
<input type="submit" class="btn btn-success " id="d1">
</form>
{% endblock %}
{% block js %}
<script>
$('#d1').click(function (){
confirm('确定要修改密码吗')
})
</script>
{% endblock %}
图书展示
图书展示的增删改查
bookListPage.html
{% extends 'home.html'%}
{% block content %}
<h1 class="text-center">图书展示页</h1>
<a href="{% url 'book_add'%}" class="btn btn-primary">图书添加</a>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>编号</th>
<th>书名</th>
<th>价格</th>
<th>日期</th>
<th>出版社</th>
<th>作者</th>
<th>operation</th>
</tr>
</thead>
<tbody>
{% for book_obj in book_queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book_obj.title }}</td>
<td>{{ book_obj.price }}</td>
<td>{{ book_obj.publish_date|date:'Y年m月d日' }}</td>
<td>{{ book_obj.publish.name }}</td>
<td>
{% for author_obj in book_obj.authors.all %}
{# 判断是不是最后一个,用逗号隔开#}
{% if forloop.last %}
{{ author_obj.name }}
{% else %}
{{ author_obj.name }},
{% endif %}
{% endfor %}
</td>
<td>
<p>
<a href="{% url 'book_edit' book_obj.pk %}" class="btn btn-primary btn-xs" >编辑</a>
<a href="{% url 'book_delete' book_obj.pk %}" class="btn btn-danger btn-xs deleteBtn">删除</a>
</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation" class="text-center">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
{% endblock %}
{% block js %}
<script>
$('.deleteBtn').click(function (){
let isDel= confirm('你确定要删除吗')
if(!isDel){
return false
}
})
</script>
{% endblock %}
bookAddPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center"> 图书添加页</h1>
<form action="" method="post">
<p>title:
<input type="text" name="title" class="form-control">
</p>
<p>price:
<input type="text" name="price" class="form-control">
</p>
<p>publish_date:
<input type="date" name="publish_date" class="form-control">
</p>
<p>publish_name:
<!-- 展示系统中已有的出版社信息供选择-->
<select name="publish_id" id="" class="form-control">
{% for publish_obj in publish_queryset %}
<option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
{% endfor %}
</select>
</p>
<p>author_list:
<!-- 展示已有作者供用户选择-->
<select name="author_id_list" id="" multiple class="form-control">
{% for author_obj in author_queryset %}
<option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
{% endfor %}
</select>
</p>
<input type="submit" value="书籍添加" class="btn btn-block btn-success">
</form>
{% endblock %}
bookEditPage.html
{% extends 'home.html' %}
{% block content %}
<h2 class="text-center"> 数据编辑页</h2>
<form action="" method="post">
<p>title:
<input type="text" name="title" class="form-control" value="{{ edit_obj.title }}">
</p>
<p>price:
<input type="text" name="price" class="form-control" value="{{ edit_obj.price }}">
</p>
<p>publish_date:
<input type="date" name="publish_date" class="form-control" value="{{ edit_obj.publish_date|date:'Y-m-d' }}">
</p>
<p>publish_name:
<!-- 展示系统中已有的出版社信息供选择-->
<select name="publish_id" id="" class="form-control">
{% for publish_obj in publish_queryset %}
<!-- 根据待编辑的书籍对象查询对应的出版社,与系统所有的出版社比对,如果相同则添加默认选中的属性 select-->
{% if edit_obj.publish == publish_obj %}
<option value="{{ publish_obj.pk }}" selected>{{ publish_obj.name }}</option>
{% else %}
<option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<p>author_list:
<!-- 展示已有作者供用户选择-->
<select name="author_id_list" id="" multiple class="form-control">
{% for author_obj in author_queryset %}
<!-- 作者是列表,用成员运算判断循环的作者对应是否再待编辑的书籍-->
{% if author_obj in edit_obj.authors.all%}
<option value="{{ author_obj.pk }}" selected>{{ author_obj.name }}</option>
{% else %}
<option value="{{ author_obj.pk }}" >{{ author_obj.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<input type="submit" value="书籍编辑" class="btn btn-block btn-block">
</form>
{% endblock %}
出版社展示
出版社的增删改查
publishListPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">出版社展示页</h1>
<a href="{% url 'publish_add' %}" class="btn btn-primary">出版社添加</a>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>编号</th>
<th>出版社名</th>
<th>出版社地址</th>
<th>operation</th>
</tr>
</thead>
{% for publish_obj in publish_queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ publish_obj.name }}</td>
<td>{{ publish_obj.address }}</td>
<td>
<a href="{% url 'publish_edit' publish_obj.pk %}" class="btn btn-primary btn-primary">编辑</a>
<a href="{% url 'publish_delete' publish_obj.pk %}" class="btn btn-success btn-danger deleteBtn">删除</a>
</td>
</tr>
{% endfor %}
<tbody>
</tbody>
</table>
{% endblock %}
{% block js %}
<script>
$('.deleteBtn').click(function (){
confirm('确定要删除吗')
})
</script>
{% endblock %}
publishAddPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">出版社添加页</h1>
<form action="" class="" method="post">
<p>name:
<input type="text" name="name" class="form-control">
</p>
<p>address:
<input type="text" name="address" class="form-control">
</p>
<input type="submit" class="btn btn-block btn-success">
</form>
{% endblock %}
publishEditPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">出版社编辑页</h1>
<form action="" method="post">
<p>name:
<input type="text" name="name" class="form-control" value="{{ edit_obj.name }} " >
</p>
<p>address:
<input type="text" name="address" class="form-control" value=" {{ edit_obj.address }}">
</p>
<input type="submit" value="出版社编辑" class="btn btn-block btn-success">
</form>
{% endblock %}
作者展示
作者的增删改查
authorListPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">作者展示页</h1>
<a href="{% url 'author_add' %}" class="btn btn-primary">作者添加</a>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>编号</th>
<th>作者名</th>
<th>年龄</th>
<th>作者号码</th>
<th>作者地址</th>
<th>operation</th>
</tr>
</thead>
{% for author_obj in author_queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author_obj.name }}</td>
<td>{{ author_obj.age }}</td>
<td>{{ author_obj.author_detail.phone }}</td>
<td>{{ author_obj.author_detail.address }}</td>
<td>
<a href="{% url 'author_edit' author_obj.pk %}" class="btn btn-primary btn-primary">编辑</a>
<a href="{% url 'author_delete' author_obj.pk %}" class="btn btn-success btn-danger deleteBtn">删除</a>
</td>
</tr>
{% endfor %}
<tbody>
</tbody>
</table>
{% endblock %}
{% block js %}
<script>
$('.deleteBtn').click(function (){
confirm('确定要删除吗')
})
</script>
{% endblock %}
authorAddPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">作者添加页</h1>
<form action="" method="post">
<p>name:
<input type="text" name="name" class="form-control">
</p>
<p>age:
<input type="text" name="age" class="form-control">
</p>
<p>author_phone:
<input type="text" name="author_phone" class="form-control">
</p>
<p>author_address:
<input type="text" name="author_address" class="form-control">
</p>
<input type="submit" value="作者添加" class="btn btn-block btn-success">
</form>
{% endblock %}
authorEditPage.html
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">作者编辑页</h1>
<form action="" method="post">
<p>name:
<input type="text" name="name" class="form-control" value="{{ edit_obj.name }}">
</p>
<p>age:
<input type="text" name="age" class="form-control" value="{{ edit_obj.age }}">
</p>
<p>author_phone:
<input type="text" name="author_phone" class="form-control" value="{{ edit_obj.author_detail.phone }}">
</p>
<p>author_address:
<input type="text" name="author_address" class="form-control" value="{{ edit_obj.author_detail.address }}">
</p>
<input type="submit" value="作者编辑" class="btn btn-block btn-success">
</form>
{% endblock %}
前端展示
首页
- 没有登录之前的首页,用户没有登录是实现不了任何功能的,必须校验登录之后才能实现功能和操作。
- 注册页面以及登录之后的页面变化
图书展示页:书籍添加、编辑以及删除
出版社展示页:书籍添加、编辑以及删除
作者展示页:书籍添加、编辑以及删除
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 解决跨域问题的这6种方案,真香!
· 分享4款.NET开源、免费、实用的商城系统
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库