Django项目实战(一):图书管理系统---单表操作版

一、效果展示

1、图书展示界面

在这里插入图片描述

2、图书删除功能

在这里插入图片描述

3、图书添加功能

在这里插入图片描述

4、图书编辑功能

在这里插入图片描述不足之处总结:

  • 有人可能会发现这个有一个比较明显的缺点,那就是删除图书后,序号没有重排,这个只要显示使用forloop.counter序号就行了,无论怎么删除图书,编号就都是连续的,我就不改了。数据库的图书主键id这个不能实现重排!除非truncate表!那就会把整个表都删除了!
  • 还有一个不足之处,其实我们完全不用自建主键,django会默认为我们创建一个自增主键,还有就是取主键值我们可以使用记录对象.pk来取(例如book_obj.pk)

二、项目目录展示

在这里插入图片描述
大致流程:
1、先把项目所用数据库准备好,改settings、\_\_init__文件把数据库连接好
2、然后设置url和视图函数映射关系,视图函数通过操作数据库,返回模板语法渲染好的页面,或者临时重定向到其他url对应的视图函数(我这里临时重定向的全是主页,因为数据修改完,就跳转到主页展示修改后的效果嘛)!
3、无论是模板中的html,还是视图函数都不要采用硬编码url,都应该使用name反向解析!

三、项目源码

1、models.py

from django.db import models


# Create your models here.

# 创建Book表
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    book_name = models.CharField(null=False, max_length=30)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publisher = models.CharField(max_length=30)

2、urls.py

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index, name="books"),
    path('books/add/', views.addbook, name="addbook"),
    re_path('^books/del/([0-9]+)/$', views.delbook, name="delbook"),
    re_path('^books/edit/([0-9]+)/$', views.editbook, name="editbook")
]

3、views.py

from django.shortcuts import render
from django.urls import reverse
from app01.models import Book
from django.shortcuts import redirect


# Create your views here.

def index(request):
    book_list = Book.objects.all()
    return render(request, "index.html", {'book_list': book_list})


def addbook(request):
    if request.method == "GET":
        return render(request, "add.html")
    else:

        '''
        <QueryDict: {'csrfmiddlewaretoken': ['7qQuzN5Wrr7T8K75mP3jlB4mW7ibMHQrRfcTHwEinyFjwS0yiX3pGXI7fR4xDHqG'], 'book_name': ['仙剑奇侠传'], 'price': ['111'], 'pub_date': ['2020-07-20'], 'publisher': ['人民出版社']}>
        将request.POST得到的queryDict对象转换成python中的dict字典
        '''
        post_dict = request.POST.dict()

        '''
        删除dict中键为csrfmiddlewaretoken的key
        这个token只是验证你是正常用户的,剩下的数据才是我们需要的
        '''
        del post_dict['csrfmiddlewaretoken']

        '''
        **打散字典,取出来就是book_name='仙剑奇侠传'这样子
        注意:form表单中的name要与数据库中的字段名一致
        '''
        Book.objects.create(**post_dict)
        return redirect(reverse("books"))


def delbook(request, book_id):
    del_book = Book.objects.filter(id=book_id)
    del_book.delete()
    return redirect(reverse('books'))

def editbook(request, book_id):
    if request.method=='GET':
        book_obj = Book.objects.get(id=book_id)
        return render(request, 'edit.html', {'book_obj':book_obj})
    else:
        post_dic = request.POST.dict()
        del post_dic['csrfmiddlewaretoken']
        Book.objects.filter(id=book_id).update(**post_dic)
        return redirect('books')

4、模板

(1)index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>图书管理系统</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .container {
            position: absolute;
            top: 250px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-lg-2">
            <a href="{% url 'addbook' %}" class="btn btn-info">添加书籍</a>
        </div>
        <div class="col-lg-8">
            <table class="table table-hover">
                <thead>
                <tr>
                    <th>图书编号</th>
                    <th>书名</th>
                    <th>价格</th>
                    <th>出版时间</th>
                    <th>出版社</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for book in book_list %}
                    <tr>
                        <td>{{ book.id }}</td>
                        <td>{{ book.book_name }}</td>
                        <td>{{ book.price }}</td>
                        <td>{{ book.pub_date|date:'Y-m-d' }}</td>
                        <td>{{ book.publisher }}</td>
                        <td>
                            <a href="{% url 'editbook' book.id %}" class="btn btn-warning btn-xs">编辑</a>
                            <a href="{% url 'delbook' book.id %}" class="btn btn-danger btn-xs">删除</a>
                        </td>
                    </tr>
                {% empty %}
                    <tr align="center">
                        <td colspan="6">暂未上架任何书籍...</td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
        <div class="col-lg-2">
        </div>
    </div>
</div>
</body>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</html>
(2)add.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>图书管理系统</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .form_area {
            width: 50%;
            position: absolute;
            top: 140px;
            left: 300px;
        }
        h3{
            position: relative;
            left: 270px;
            margin-bottom: 20px;
            font-family: "Kaiti SC";
            font-weight: bold;
        }
    </style>
</head>
<body>
<div class="form_area">
    {% block table_name %}
        <h3>书籍添加信息表</h3>
    {% endblock %}

    {% block form_head %}
        <form class="form-horizontal" action="{% url 'addbook' %}" method="post">
    {% endblock %}

        {% csrf_token %}
        <div class="form-group">
            <label for="inputbookname" class="col-sm-2 control-label">书名</label>
            <div class="col-sm-10">
                {% block inputbookname %}
                    <input type="text" class="form-control" id="inputbookname" placeholder="请输入书籍名称" name="book_name">
                {% endblock %}
            </div>
        </div>
        <div class="form-group">
            <label for="inputprice" class="col-sm-2 control-label">价格</label>
            <div class="col-sm-10">
                {% block inputprice %}
                    <input type="text" class="form-control" id="inputprice" placeholder="请输入价格" name="price">
                {% endblock %}
            </div>
        </div>
        <div class="form-group">
            <label for="inputdate" class="col-sm-2 control-label">出版时间</label>
            <div class="col-sm-10">
                {% block inputdate %}
                    <input type="date" class="form-control" id="inputdate" placeholder="请输入书籍出版时间" name="pub_date">
                {% endblock %}
            </div>
        </div>
        <div class="form-group">
            <label for="inputpublisher" class="col-sm-2 control-label">出版社</label>
            <div class="col-sm-10">
                {% block inputpublisher %}
                    <input type="text" class="form-control" id="inputpublisher" placeholder="请输入书籍出版社" name="publisher">
                {% endblock %}
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                {% block button_sub %}
                    <button type="submit" class="btn btn-success center-block">提交</button>
                {% endblock %}
            </div>
        </div>
{% block form_tail %}
    </form>
{% endblock %}

</div>
</body>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</html>
(3)edit.html

由于本页面和add.html及其相似,因此这里采用了模板继承

{% extends 'add.html' %}

{% block table_name %}
    <h3>书籍信息编辑表</h3>
{% endblock table_name %}

{% block form_head %}
    <form class="form-horizontal" action="{% url 'editbook' book_obj.id %}" method="post">
{% endblock form_head %}

{% block inputbookname %}
    <input type="text" class="form-control" id="inputbookname" value="{{ book_obj.book_name }}" name="book_name">
{% endblock %}
{% block inputprice %}
    <input type="text" class="form-control" id="inputprice" value="{{ book_obj.price }}" name="price">
{% endblock %}

{% block inputdate %}
    <input type="date" class="form-control" id="inputdate" value="{{ book_obj.pub_date|date:'Y-m-d' }}" name="pub_date">
{% endblock %}

{% block inputpublisher %}
    <input type="text" class="form-control" id="inputpublisher" value="{{ book_obj.publisher }}" name="publisher">
{% endblock %}

{% block button_sub %}
    <button type="submit" class="btn btn-success center-block">提交修改</button>
{% endblock button_sub %}

{% block form_tail %} # 必须加一个这个,不然会报错!如下图
    </form>
{% endblock %}

在这里插入图片描述

三、实验收获总结

1、path、url、re_path的区别

path是django2之后使用的代替url的,但是path不支持正则,因此re_path就是支持正则的,它和url一样!

2、**打散方法添加数据

注意:form表单中的name要与数据库中的字段名一致

'''
        <QueryDict: {'csrfmiddlewaretoken': ['7qQuzN5Wrr7T8K75mP3jlB4mW7ibMHQrRfcTHwEinyFjwS0yiX3pGXI7fR4xDHqG'], 'book_name': ['仙剑奇侠传'], 'price': ['111'], 'pub_date': ['2020-07-20'], 'publisher': ['人民出版社']}>
        将request.POST得到的queryDict对象转换成python中的dict字典
        '''
        post_dict = request.POST.dict()

        '''
        删除dict中键为csrfmiddlewaretoken的key
        这个token只是验证你是正常用户的,剩下的数据才是我们需要的
        '''
        del post_dict['csrfmiddlewaretoken']

        '''
        **打散字典,取出来就是book_name='仙剑奇侠传'这样子
        注意:form表单中的name要与数据库中的字段名一致
        '''
        Book.objects.create(**post_dict)
        return redirect(reverse("books"))

3、动态url的反向解析方法

模板语法中的动态url的反向解析:

<a href="{% url 'editbook' book.id %}" class="btn btn-warning btn-xs">编辑</a>
<a href="{% url 'delbook' book.id %}" class="btn btn-danger btn-xs">删除</a>

视图函数中的动态url的反向解析:

return redirect(reverse("books",args()))
# args就是放置动态参数的,按动态参数在url中的位置依次放置!

猜你喜欢

转载自blog.csdn.net/weixin_44571270/article/details/107536873
今日推荐