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

发布时间:2024年01月11日

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

1.创建图书管理表

添加了一些简易的字段,主要是为了熟悉Django ORM框架。需要增添其他复杂字段,可以修改Model模型,使用迁移命令,修改数据库。
1.1.1创建图书模型
在项目目录下的models.py文件添加新的类

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 manage.py makemigrations

应用数据库迁移:

python manage.py migrate

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

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

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

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

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

<!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

 path('upload_book/', book_controller.upload_book, name='upload_book'),

完成效果如下:
在这里插入图片描述

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

有了数据之后,就可以做查询功能了,直接使用Django为我们创建好的API。
首先,新建一个查询所有图书的函数。

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

列出所有图书信息的话,直接用all就可以了,不用加filter,返回给模板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

  path('book_list/', book_controller.get_all_books, name='get_all_books'),

显示如下:
在这里插入图片描述

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

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

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信息返回给编辑页面

<!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>

效果如下:
在这里插入图片描述
最后处理修改后的数据。

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

	path('books/<int:id>/edit/', book_controller.get_book_by_id),
	path('edit_book/', book_controller.edit_book, name='edit_book'),

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

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

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

    path('delete_book/<int:id>/', book_controller.delete_book),
文章来源:https://blog.csdn.net/weixin_46999174/article/details/135524134
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。