使用Django框架实现简单的图书借阅系统——完成图书信息管理

书接上回: Django 框架添加管理员,完成对普通用户信息管理

文章目录

1.创建图书管理表

添加了一些简易的字段,主要是为了熟悉Django ORM框架。需要增添其他复杂字段,可以修改Model模型,使用迁移命令,修改数据库。

1.1.1创建图书模型

在项目目录下的models.py文件添加新的类

python 复制代码
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    details = models.TextField()
    image_link = models.CharField(max_length=200)

    def __str__(self):
        return self.title

属性定义了Book模型的字段。以下是每个字段表示的含义:

  • title:一个最大长度为100字符的字符字段(字符串)。
  • author:另一个字符字段,用于存储作者的名字,同样最大长度为100字符。
  • details:用于存储有关书籍的其他详细信息的文本字段。此字段可以存储较长的文本。
  • image_link:用于存储书籍图片链接的字符字段,最大长度为200字符。
    创建好类之后,在终端运行Django命令 让框架帮我们生成数据库表

创建数据库迁移文件:

python 复制代码
python manage.py makemigrations

应用数据库迁移:

powershell 复制代码
python manage.py migrate

确保在每次对模型进行更改后都运行这两个命令,以保持数据库结构与模型定义同步。如果在模型中添加、修改或删除字段,Django会生成相应的迁移文件,并通过迁移命令应用这些更改。

2.增加上传图书信息功能

上一篇博客已经讲述了 Django的form表单,这里不过赘述。创建一个Django 图书信息表单,在目录下的forms.py 添加一个BookForm类 (如果没有forms.py 手动创建即可 )

python 复制代码
class BookForm(forms.ModelForm):
    title = forms.CharField(
        label="图书名字",

    )
    author = forms.CharField(
        label="作者",
    )

    image_link = forms.CharField(
        label="图片链接",
    )
    class Meta:
        model = Book
        fields = ['title', 'author', 'details', 'image_link']

添加好表单之后,创建book 增删改查的视图,笔者这里命名为book_controller.py

python 复制代码
def upload_book(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/book_list')  # 重定向到图书列表页面或其他适当的页面
    else:
        form = BookForm()
    return render(request, 'book/upload_book.html', {'form': form})

创建上传图书信息模板HTML

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>注册</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <!-- 引入 Bootstrap 样式表 -->
    <style>
        /* 自定义额外样式 */
        .form-signup {
            max-width: 400px;
            margin: 0 auto;
            padding: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f9f9f9;
        }

        .form-signup h2 {
            margin-bottom: 20px;
        }

        .form-signup label {
            font-weight: bold;
            display: block;
            margin-bottom: 5px; /* 调整标签和输入框之间的间距 */
        }

        .form-signup input[type="text"],
        .form-signup input[type="password"],
        .form-signup input[type="email"] {
            width: 100%;
            padding: 8px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }

        .form-signup .btn-primary {
            margin-top: 20px;
        }
    </style>
</head>
<body>

<div class="container mt-5">
    <h2 class="text-center mb-4">添加图书信息</h2>
    <form method="post" class="form-signup">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary btn-block">上传</button>
    </form>
</div>

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<!-- 引入 Bootstrap JavaScript -->
</body>
</html>

绑定URL

在urls.py增添path

python 复制代码
 path('upload_book/', book_controller.upload_book, name='upload_book'),

完成效果如下:

3.增加查询图书信息功能

有了数据之后,就可以做查询功能了,直接使用Django为我们创建好的API。

首先,新建一个查询所有图书的函数。

python 复制代码
def get_all_books(request):
    # 查询所有图书
    books = Book.objects.all()
    return render(request, 'book/book_list.html', {'books': books})

列出所有图书信息的话,直接用all就可以了,不用加filter,返回给模板HTML。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>管理菜单</title>
    <style>
        /* 菜单样式 */
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }

        .sidebar {
            width: 250px;
            background-color: #333;
            height: 100%;
            position: fixed;
            left: 0;
            top: 0;
            overflow-x: hidden;
        {#padding-top: 20px;#}
        }

        .sidebar a {
            padding: 10px 16px;
            margin: 20px;
            text-decoration: none;
            font-size: 22px;
            color: #85f112;
            display: block;
            transition: 0.3s;

        }

        .sidebar a:hover {
            background-color: #0edcac;
            color: black;
        }

        .content {
            margin-left: 250px;
            padding: 20px;
        }

        .header {
            background-color: #f1f1f1;
            padding: 10px;
            text-align: center;
        }

        {#    美化表格#}
        table {
            border-collapse: collapse;
            width: 100%;
        }

        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }

        th {
            background-color: #f2f2f2;
        }

        tr:nth-child(even) {
            background-color: #f9f9f9;
        }

        .button {
            display: inline-block;
            padding: 10px 20px;
            margin-bottom: 10px;
            text-decoration: none;
            color: #fff;
            background-color: #007bff;
            border: 1px solid #007bff;
            border-radius: 4px;
            transition: background-color 0.3s;
        }

        .button:hover {
            background-color: #0056b3;
            border-color: #0056b3;
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 20px;
        }

        .header-content {
            margin-left: auto;
        }

    </style>
</head>
<body>

<div class="sidebar">
    <div class="header">
        <h2>管理菜单</h2>
    </div>
    <a href="../user_list/">用户管理</a>
    <a href="../book_list/">图书管理</a>
    <a href="../borrow_list/">借阅管理</a>
    <a href="../migrations_list/">迁移记录</a>
</div>

<div class="content">
    <!-- 这里是你的主要内容 -->

        <h2>图书列表</h2>
          <div class="header-content">

          </div>


    <table>
        <tr>
            <th>编号</th>
            <th>书名</th>
            <th>作者</th>
            <th>详情</th>
            <th>图片链接</th>
            <th>操作</th>
            <!-- 这里可以根据需要显示其他字段 -->
        </tr>
        {% for book in books %}
            <tr>
                <td>{{ book.id }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.details }}</td>
                <td>{{ book.image_link }}</td>
                <td>
                    {#                注意这里路径写法#}
                    <a href="../books/{{ book.id }}/edit/">修改</a> &nbsp; <a
                        href="../delete_book/{{ book.id }}/">删除</a>
                </td>
                <!-- 这里可以根据需要显示其他字段 -->
            </tr>
        {% endfor %}
    </table>

      <a href="../upload_book/" class="button" style="margin-top: 20px">添加图书信息</a>

</div>

</body>
</html>

最后绑定urls.py

python 复制代码
  path('book_list/', book_controller.get_all_books, name='get_all_books'),

显示如下:

4.增加修改图书信息功能

一般来讲只要获取到id,首先根据id查询图书信息之后,将图书信息返回给编辑页面。编辑页面与上传信息页面基本上一样,可以进行优化,根据ID的值来判断是上传信息还是编辑信息,ID为零或者没有ID代表是上传信息,ID有值代表是编辑。这里只是简单学习框架,并未进行优化。

分为两步,先根据ID查询图书信息,回显,编辑新的数据,上传。

python 复制代码
def get_book_by_id(request, id):
    # 根据ID查询book
    book = Book.objects.filter(id=id).first()
    return render(request, 'book/edit_book.html', {'book': book})

将book信息返回给编辑页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改图书信息</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f7f7f7;
        }
        form {
            max-width: 420px;
            margin: 0 auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }

        textarea{
            width: 95%;
            padding: 8px;
            height:200px ;

            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 3px;
        }
        input[type="text"],
        input[type="password"],

        input[type="email"] {
            width: 95%;
            padding: 8px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 3px;
        }
        button {
            padding: 10px 20px;
            border: none;
            border-radius: 3px;
            background-color: #4caf50;
            color: white;
            cursor: pointer;

            width: 100%;
        }
        button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <form method="post" action="/edit_book/">
        {% csrf_token %}
        <h2 style="text-align: center">修改图书信息</h2>
        <input type="hidden" name="id" value="{{ book.id }}">
        <label for="title">图书名称:</label>
        <input type="text" id="title" name="title" value="{{ book.title }}" ><br><br>
         <label for="author">作者:</label>
        <input type="text" id="author" name="author" value="{{ book.author }}" ><br><br>
         <label for="detail">详情:</label>
        <textarea  id="details" name="details" >
            {{ book.details }}
        </textarea><br><br>
     <label for="image_link">图片链接:</label>
        <input type="text" id="image_link" name="image_link" value="{{ book.image_link }}" ><br><br>

        <button type="submit">修改</button>
    </form>
</body>
</html>

效果如下:

最后处理修改后的数据。

python 复制代码
def edit_book(request):
    if request.method == 'POST':
        book_id = request.POST.get('id')
        book = get_object_or_404(Book, id=book_id)  # 根据ID查询已经存在的book对象
        form = BookForm(request.POST, instance=book)
        if form.is_valid():
            # 更新这个对象的数据
            form.save()
            return redirect('/book_list')  # 重定向到图书列表页面或其他适当的页面
    else:
        form = BookForm()
    return render(request, 'book/upload_book.html', {'form': form})

与上传信息有所不同,首先根据ID对象查询出已经有的对象。创建一个BookForm表单实例,使用POST请求的数据和之前获取的书籍对象作为参数。这样,表单将尝试绑定到该书籍对象,允许我们编辑它的属性。如果表单有效,将会更新这个对象,并存放到数据库,这样就完成了更新数据功能。

最后绑定urls.py

python 复制代码
	path('books/<int:id>/edit/', book_controller.get_book_by_id),
	path('edit_book/', book_controller.edit_book, name='edit_book'),

5.完成删除图书信息功能

查询到图书信息,封装成对象,调用delete 即可

python 复制代码
def delete_book(request, id):
    try:
        book = Book.objects.filter(id=id).first()
        book.delete()
        return redirect('/book_list')
    except Book.DoesNotExist:
        return HttpResponse('图书不存在')

最后绑定urls.py

python 复制代码
    path('delete_book/<int:id>/', book_controller.delete_book),
相关推荐
运维李哥不背锅1 小时前
Ansible 的条件语句与循环详解
数据库·ansible
曾凡宇先生2 小时前
OpenEuler中mysql这是在执行 MySQL 密码重置操作时出现的 “找不到mysqld_safe命令” 的错误场景。
数据库·mysql
方二华2 小时前
6 mysql源码中的查询逻辑
数据库·mysql
意疏2 小时前
LibreTV无广告观影实测:聚合全网资源,远程访问家庭影院新方案!
数据库
不见长安在3 小时前
mysql线上主从集群设置
数据库·mysql
tiging3 小时前
mysql 如何让事件执行
数据库·mysql
siriuuus3 小时前
MySQL 数据备份
数据库·mysql·备份
姚远Oracle ACE3 小时前
Oracle AWR 报告中的SQL来自哪儿?
数据库·sql·oracle
熊文豪3 小时前
KingbaseES数据库性能调优工具全面解析
数据库·kingbasees·金仓数据库·电科金仓
冠希陈、3 小时前
PHP7.4.33 安装sqlsrv扩展
数据库