django+mysql:图书管理系统

系统界面

1、图书管理系统:

图片.png

2、作者管理系统:

图片.png

3、出版社管理系统:

图片.png

项目目录

目录结构如下图,在应用app03中实现相关功能:


图片.png

项目代码

Book_Manage中的url文件如下:

from django.contrib import admin
from django.urls import path, re_path
from django.conf.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('app03/',include(('app03.urls','app03'),namespace='app03')),
]

app03中的urls文件如下:

from django.urls import path, re_path
from app03 import views

urlpatterns = [
    path('', views.book_view, name='book_view'),
    path('books/add', views.book_add, name='book_add'),
    path('author/', views.author_view, name='author_view'),
    path('author/add/', views.author_add, name='author_add'),
    path('publisher/', views.publisher_view, name='publisher_view'),
    path('publisher/add/', views.publisher_add, name='publisher_add'),
    re_path('books/del/(?P<del_book_id>[0-9]+)/', views.book_del, name='book_del'),
    re_path('books/edit/(?P<edit_book_id>[0-9]+)/', views.book_edit, name='book_edit'),
    re_path('author/del/([0-9]+)', views.author_del, name='author_del'),
    re_path('author/edit/([0-9]+)', views.author_edit, name='author_edit'),
    re_path('publisher/del/([0-9]+)', views.publisher_del, name='publisher_del')
]

app03中的models.py文件如下:

from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=30)
    price = models.IntegerField()
    pub_date = models.DateField()
    authors = models.ManyToManyField(to="Authors")  # 多对多
    publish = models.ForeignKey(to="Publisher", on_delete=models.CASCADE)  # 一对多,只有外键才有级联删除这一说。多对多是另外开一张表,不存在

    def __str__(self):
        return self.name

class Authors(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    ad = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    email = models.EmailField()
    tel_phone = models.IntegerField()

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()

    def __str__(self):
        return self.name

app03中的views.py文件如下:

from django.shortcuts import render
from app03.models import Book, Publisher, Authors, AuthorDetail
from django.shortcuts import redirect, reverse
from django.http import HttpResponse
import json

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

def book_add(request):
    if request.method == 'GET':
        publisher_list = Publisher.objects.all()
        author_list = Authors.objects.all()
        return render(request, 'app03/add.html', {'publisher_list': publisher_list, 'author_list': author_list})
    else:
        name = request.POST.get('name')
        price = request.POST.get('price')
        pub_date = request.POST.get('pub_date')
        publisher_id = request.POST.get('publisher_id')
        authors_id = request.POST.getlist('authors_id[]')  # 这里得到的是一个author列表
        book = Book.objects.create(name=name, price=price, pub_date=pub_date, publish_id=publisher_id)
        book.authors.add(*authors_id)  # *号:列表打散
        print(book.authors.add(*authors_id))
        return redirect(reverse('app03:book_view'))

def book_del(request, del_book_id):
    response = {'status': True}
    try:
        Book.objects.get(pk=del_book_id).delete()
    except Exception:
        response['status'] = False
    return HttpResponse(json.dumps(response))

def book_edit(request, edit_book_id):
    book_obj = Book.objects.filter(pk=edit_book_id).first()
    if request.method == 'GET':
        publisher_list = Publisher.objects.all()
        author_list = Authors.objects.all()
        return render(request, 'app03/edit.html',
                      {'book_obj': book_obj, 'publisher_list': publisher_list, 'author_list': author_list})
    else:
        name = request.POST.get('name')
        price = request.POST.get('price')
        pub_date = request.POST.get('pub_date')
        publisher_id = request.POST.get('publisher_id')
        authors_id = request.POST.getlist('authors_id[]')
        Book.objects.filter(pk=edit_book_id).update(name=name, price=price, pub_date=pub_date, publish_id=publisher_id)
        #filter(pk=edit_book_id).update():对当前指定的记录进行更新
        book_obj.authors.set(*authors_id)
        return redirect(reverse('app03:book_view'))

def author_view(request):
    author_list = Authors.objects.all()
    return render(request, 'app03/author_view.html', {'author_list': author_list})

def author_add(request):
    name = request.POST.get('name')
    age = request.POST.get('age')
    email = request.POST.get('email')
    tel_number = request.POST.get('tel_number')
    ad_obj = AuthorDetail.objects.create(email=email, tel_phone=tel_number)
    Authors.objects.create(name=name, age=age, ad_id=ad_obj.pk)
    return redirect(reverse('app03:author_view'))

def author_del(request, del_author_id):
    response = {'status': True}
    try:
        Authors.objects.get(pk=del_author_id).delete()
    except Exception:
        response['status'] = False
    return HttpResponse(json.dumps(response))

def author_edit(request, edit_author_id):
    author_obj = Authors.objects.get(pk=edit_author_id)
    if request.method == 'GET':
        return render(request, 'app03/author_edit.html', {'author_obj': author_obj})
    else:
        name = request.POST.get('name')
        age = request.POST.get('age')
        email = request.POST.get('email')
        tel_number = request.POST.get('tel_number')
        AuthorDetail.objects.filter(pk=author_obj.ad_id).update(email=email, tel_phone=tel_number)
        Authors.objects.filter(pk=edit_author_id).update(name=name, age=age)
        return redirect(reverse('app03:author_view'))

def publisher_view(request):
    publisher_list = Publisher.objects.all()
    return render(request, 'app03/publisher_view.html', {'publisher_list': publisher_list})

def publisher_add(request):
    name = request.POST.get('name')
    email = request.POST.get('email')
    Publisher.objects.create(name=name, email=email)
    return redirect(reverse('app03:publisher_view'))

def publisher_del(request, del_publisher_id):
    print(del_publisher_id)
    response = {'status': True}
    try:
        Publisher.objects.get(pk=del_publisher_id).delete()
    except Exception as e:
        response['status'] = False
    return HttpResponse(json.dumps(response))

模板

(1)图书管理系统相关

【1】index.html(templates/app03/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">
    {% block page_title %}
        <title>图书管理系统</title>
    {% endblock %}
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .table_area {
            width: 800px;
            position: absolute;
            top: 150px;
            left: 250px;
        }

        .add_btn {
            font-size: 18px;
            font-family: "Kaiti SC";
            font-weight: bolder;
        }

        .sys-menu {
            position: relative;
            top: auto;
            left: 35px;
            width: 150px;
            height: 200px;
        }

        .page_top {
            background-color: #146896;
            width: 100%;
            height: 50px;
        }

        .panel-heading {
            text-align: center;
            font-weight: bolder;
        }

        .panel-body {
            text-align: center;
            width: 100%;
        }

        .panel-body > a {
            text-decoration: none;
        }

        .panel-body > a:hover {
            color: skyblue;
        }

        .active{
            background-color: blanchedalmond;
        }

        #exampleModalLabel{
            font-family: "Kaiti SC";
            font-size: 20px;
            font-weight: bolder;
        }
    </style>
</head>
<body>
<div class="page_top"></div>
<div class="panel panel-default sys-menu nav nav-pills">
    <div class="panel-heading">
        功能系统
    </div>
{% block sys_view %}
    <div class="panel-body active">
        <a href="{% url 'app03:book_view' %}">图书管理系统</a>
    </div>
    <div class="panel-body">
        <a href="{% url 'app03:author_view' %}">作者管理系统</a>
    </div>
    <div class="panel-body">
        <a href="{% url 'app03:publisher_view' %}">出版社管理系统</a>
    </div>
{% endblock %}
</div>
{% block master_content %}
    <div class="table_area">
        {% csrf_token %}
        <table class="table table-hover">
            <thead>
            <tr>
                <th>书籍编号</th>
                <th>书名</th>
                <th>价格</th>
                <th>出版时间</th>
                <th>出版社</th>
                <th>作者</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            {% for book_obj in book_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ book_obj.name }}</td>
                    <td>{{ book_obj.price }}</td>
                    <td>{{ book_obj.pub_date|date:'Y-m-d' }}</td>
                    <td>{{ book_obj.publish.name }}</td>
                    <td>
                        {% for author_obj in book_obj.authors.all %} <!--book_obj.authors.all得到的是一个作者对象的queryset-->
                            {% if forloop.last %}
                                <!--
                                    有人会问这里不是对象吗?为什么打印对象?不应该是author_obj.name吗?
                                    我在model中写了双下方法str的
                                -->
                                {{ author_obj }}
                            {% else %}
                                {{ author_obj }},
                            {% endif %}

                        {% endfor %}
                    </td>
                    <td>
                        <a href="{% url 'app03:book_edit' book_obj.pk %}" class="btn btn-warning btn-xs">编辑</a>
                        <!-- 删除我们应该使用ajax进行局部刷新,不应该和编辑一样使用页面刷新 -->
                        <a id="del_book" class="btn btn-danger btn-xs" book_id={{ book_obj.pk }}>删除</a>
                    </td>
                </tr>
                {% if forloop.last and forloop.counter > 0 %}
                    <tr>
                        <td colspan="7">
                            <a href="{% url 'app03:book_add' %}" class="btn btn-info btn-xs form-control add_btn">添加书籍</a>
                        </td>
                    </tr>
                {% endif %}
            {% empty %}
                <tr align="center">
                    <td colspan="7">
                        暂未上架任何书籍... <br>
                        <span>请点击:<a href="{% url 'app03:book_add' %}" class="btn btn-info btn-xs">添加书籍</a></span>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}
</body>
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
{% block script_area %}
    <script>
        $(function () {
            $("tbody").on('click', '#del_book', function () {
                let $ele = $(this).parent().parent()
                //$(this)指当前元素,即id为'del_book'的删除按钮
                //即:<a id="del_book" class="btn btn-danger btn-xs" book_id={{ book_obj.pk }}>删除</a>
                //$(this).attr('book_id')可获得删除按钮对应的book_id={{ book_obj.pk }},即当前按钮所在行的书籍id。
                $.ajax({
                    url: `/app03/books/del/${$(this).attr('book_id')}/`,
                    //为什么这么写?${$(this).attr('book_id')}
                    type: "post",
                    data: {
                        csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
                    },
                    success: function(response) {
                        response = JSON.parse(response)
                        if (response["status"] == true) {
                            $ele.remove()
                            //$ele指当前删除按钮的父元素td的父元素tr,即删除按钮所在行
                        } else {
                            alert('书籍删除失败!请重试')
                        }
                    }
                })
            })
        })
    </script>
{% endblock %}
</html>

【2】add.html(templates/app03/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>
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在bootstrap前边) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .form-area {
            width: 600px;
            position: absolute;
            top: 130px;
            left: 300px;
        }

        h3 {
            position: relative;
            left: 270px;
            margin-bottom: 20px;
            font-family: "Kaiti SC";
            font-weight: bold;
        }

        .center-block {
            position: relative;
            left: 50px;
        }

        .author_add {
            position: relative;
            top: 20px;
        }

        #inputauthor {
            height: 75px;
        }
    </style>
</head>
<body>
<div class="form-area">
    {% block form_title %}
        <h3>书籍添加信息表</h3>
    {% endblock form_title %}
    {% block form_head %}
        <form class="form-horizontal" action="{% url 'app03:book_add' %}" method="post">
    {% endblock form_head %}
    {% csrf_token %}
    <div class="form-group">
        <label for="inputname" class="col-sm-2 control-label">书名</label>
        <div class="col-sm-10">
            {% block inputname %}
                <input type="text" class="form-control" id="inputname" placeholder="请输入书籍名称" name="name">
            {% endblock inputname %}
        </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 inputprice %}
        </div>
    </div>
    <div class="form-group">
        <label for="input_pub_date" class="col-sm-2 control-label">出版时间</label>
        <div class="col-sm-10">
            {% block input_pub_date %}
                <input type="date" class="form-control" id="input_pub_date" name="pub_date">
            {% endblock input_pub_date %}
        </div>
    </div>
    <div class="form-group">
        <label for="inputpublisher" class="col-sm-2 control-label">出版社</label>
        <div class="col-sm-10">
            {% block inputpublisher %}
                <select name="publisher_id" id="inputpublisher" class="form-control">
                    {% for publish_obj in publisher_list %}
                        <option value="{{ publish_obj.pk }}">{{ publish_obj }}</option>
                    {% endfor %}
                </select>
            {% endblock inputpublisher %}
        </div>
    </div>
    <div class="form-group">
        <label for="inputauthor" class="col-sm-2 control-label author_add">作者</label>
        <div class="col-sm-10">
            {% block inputauthor %}
                <select name="authors_id[]" id="inputauthor" class="form-control" multiple>
                    {% for author_obj in author_list %}
                        <option value="{{ author_obj.pk }}">{{ author_obj }}</option>
                    {% endfor %}
                </select>
            {% endblock inputauthor %}
        </div>
    </div>
    {% block submit %}
        <input type="submit" class="btn btn-success center-block" value="提交">
    {% endblock submit %}
    {% block form-tail %}
        </form>
    {% endblock form-tail %}
</div>
</body>
</html>

【3】edit.html(templates/app03/edit.html)

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

{% extends 'app03/add.html' %}
{% block form_title %}
    <h3>书籍信息编辑表</h3>
{% endblock form_title %}

{% block form_head %}
    <form class="form-horizontal" action="{% url 'app03:book_edit' book_obj.pk %}" method="post">
{% endblock form_head %}

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

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

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

{% block inputpublisher %}
    <select name="publisher_id" id="inputpublisher" class="form-control">
        {% for publish_obj in publisher_list %}
            {% if book_obj.publish == publish_obj %}
                <option value="{{ publish_obj.pk }}" selected>{{ publish_obj }}</option>
            {% else %}
                <option value="{{ publish_obj.pk }}">{{ publish_obj }}</option>
            {% endif %}
        {% endfor %}
    </select>
{% endblock inputpublisher %}

{% block inputauthor %}
    <select name="authors_id[]" id="inputauthor" multiple class="form-control">
        {% for author_obj in author_list %}
            {% if author_obj in book_obj.authors.all %}
                <option value="{{ author_obj.pk }}" selected>{{ author_obj }}</option>
            {% else %}
                <option value="{{ author_obj.pk }}">{{ author_obj }}</option>
            {% endif %}
        {% endfor %}
    </select>
{% endblock inputauthor %}

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

{% block form-tail %}
    </form>
{% endblock form-tail %}

(2)作者管理系统相关

【1】author_view.html(templates/app03/author_view.html)

{% extends 'app03/index.html' %}
{% block page_title %}
    <title>作者管理系统</title>
{% endblock %}
{% block sys_view %}
    <div class="panel-body">
        <a href="{% url 'app03:book_view' %}">图书管理系统</a>
    </div>
    <div class="panel-body active">
        <a href="{% url 'app03:author_view' %}">作者管理系统</a>
    </div>
    <div class="panel-body">
        <a href="{% url 'app03:publisher_view' %}">出版社管理系统</a>
    </div>
{% endblock sys_view %}
{% block master_content %}
    <div class="table_area">
        {% csrf_token %}
        <table class="table table-hover">
            <thead>
            <tr>
                <th>作者编号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>邮箱</th>
                <th>手机号码</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            {% for author_obj in author_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ author_obj.name }}</td>
                    <td>{{ author_obj.age }}</td>
                    <td>{{ author_obj.ad.email }}</td>
                    <td>{{ author_obj.ad.tel_phone }}</td>
                    <td>
                        <a href="{% url 'app03:author_edit' author_obj.pk %}" class="btn btn-warning btn-xs ">编辑</a>
                        <!-- 删除我们应该使用ajax进行局部刷新,不应该和编辑一样使用页面刷新 -->
                        <a id="del_author" class="btn btn-danger btn-xs" author_id={{ author_obj.pk }}>删除</a>
                    </td>
                </tr>
                {% if forloop.last and forloop.counter > 0 %}
                    <tr>
                        <td colspan="7">
                            <a type="button" class="btn btn-info form-control add_btn" data-toggle="modal"
                               data-target="#exampleModal"
                               data-whatever="@mdo">添加作者
                            </a>

                            <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog"
                                 aria-labelledby="exampleModalLabel">
                                <div class="modal-dialog" role="document">
                                    <div class="modal-content">
                                        <div class="modal-header">
                                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                                <span aria-hidden="true">&times;</span></button>
                                            <h4 class="modal-title" id="exampleModalLabel" >作者信息添加表</h4>
                                        </div>
                                        <div class="modal-body">
                                            <form action="{% url 'app03:author_add' %}" method="post">
                                                {% csrf_token %}
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">姓名</label>
                                                    <input type="text" class="form-control" id="recipient-name" name="name">
                                                </div>
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">年龄</label>
                                                    <input type="text" class="form-control" id="recipient-name" onkeyup="value=value.replace(/[^\d]/g,'')" maxlength="3" name="age">
                                                </div>
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">邮箱</label>
                                                    <input type="email" class="form-control" id="recipient-name" name="email">
                                                </div>
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">手机号码</label>
                                                    <input type="text" class="form-control" id="recipient-name" onkeyup="value=value.replace(/[^\d]/g,'')" maxlength="11" name="tel_number">
                                                </div>
                                                <div class="modal-footer">
                                                    <button type="submit" class="btn btn-primary">提交</button>
                                                </div>
                                            </form>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </td>
                    </tr>
                {% endif %}
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

{% block script_area %}
    <script>
        $(function () {
            $("tbody").on('click', '#del_author', function () {
                let $ele = $(this).parent().parent()
                $.ajax({
                    url: `/app03/author/del/${$(this).attr('author_id')}/`,
                    type: "post",
                    data: {
                        csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
                    },
                    success: function (response) {
                        response = JSON.parse(response)
                        if (response["status"] == true) {
                            $ele.remove()
                        } else {
                            alert('作者删除失败!请重试')
                        }
                    }
                })
            })
        })
    </script>
{% endblock %}

【2】author_edit.html(templates/app03/author_edit.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/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .form-area {
            width: 600px;
            position: absolute;
            top: 130px;
            left: 300px;
        }

        h3 {
            position: relative;
            left: 270px;
            margin-bottom: 20px;
            font-family: "Kaiti SC";
            font-weight: bold;
        }

        .center-block {
            position: relative;
            left: 50px;
        }

    </style>
</head>
<body>
<div class="form-area">
    <h3>作者信息编辑表</h3>
    <form class="form-horizontal" action="{% url 'app03:author_edit' author_obj.pk %}" method="post">
        {% csrf_token %}
        <div class="form-group">
            <label for="input_name" class="col-sm-2 control-label">姓名</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="input_name"  value="{{ author_obj.name }}" name="name">
            </div>
        </div>
        <div class="form-group">
            <label for="input_age" class="col-sm-2 control-label">年龄</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="input_age"  value="{{ author_obj.age }}" onkeyup="value=value.replace(/[^\d]/g,'')" maxlength="3" name="age">
            </div>
        </div>
        <div class="form-group">
            <label for="input_email" class="col-sm-2 control-label">邮箱</label>
            <div class="col-sm-10">
                <input type="email" class="form-control" id="input_email"  value="{{ author_obj.ad.email }}" name="email">
            </div>
        </div>
        <div class="form-group">
            <label for="input_tel_number" class="col-sm-2 control-label">手机号码</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" id="input_tel_number" value="{{ author_obj.ad.tel_phone }}" onkeyup="value=value.replace(/[^\d]/g,'')" maxlength="11" name="tel_number">
            </div>
        </div>
        <input type="submit" class="btn btn-success center-block" value="提交">
    </form>
</div>
</body>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在bootstrap前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
</html>

(3)出版社管理系统相关

【1】publisher_view.html(templates/app03/publisher_view.html)

{% extends 'app03/index.html' %}
{% block page_title %}
    <title>出版社管理系统</title>
{% endblock %}

{% block sys_view %}
    <div class="panel-body">
        <a href="{% url 'app03:book_view' %}">图书管理系统</a>
    </div>
    <div class="panel-body">
        <a href="{% url 'app03:author_view' %}">作者管理系统</a>
    </div>
    <div class="panel-body active">
        <a href="{% url 'app03:publisher_view' %}">出版社管理系统</a>
    </div>
{% endblock %}

{% block master_content %}
    <div class="table_area">
        {% csrf_token %}
        <table class="table table-hover">
            <thead>
            <tr>
                <th>出版社编号</th>
                <th>名称</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            {% for publisher_obj in publisher_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ publisher_obj.name }}</td>
                    <td>{{ publisher_obj.email }}</td>
                    <td>
                        <!-- 删除我们应该使用ajax进行局部刷新,不应该和编辑一样使用页面刷新 -->
                        <a id="del_publisher" class="btn btn-danger btn-xs" publisher_id={{ publisher_obj.pk }}>删除</a>
                    </td>
                </tr>
                {% if forloop.last and forloop.counter > 0 %}
                    <tr>
                        <td colspan="7">
                            <a type="button" class="btn btn-info form-control add_btn" data-toggle="modal"
                               data-target="#exampleModal"
                               data-whatever="@mdo">添加出版社
                            </a>

                            <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog"
                                 aria-labelledby="exampleModalLabel">
                                <div class="modal-dialog" role="document">
                                    <div class="modal-content">
                                        <div class="modal-header">
                                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                                <span aria-hidden="true">&times;</span></button>
                                            <h4 class="modal-title" id="exampleModalLabel" >出版社信息添加表</h4>
                                        </div>
                                        <div class="modal-body">
                                            <form action="{% url 'app03:publisher_add' %}" method="post">
                                                {% csrf_token %}
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">名称</label>
                                                    <input type="text" class="form-control" id="recipient-name" name="name">
                                                </div>
                                                <div class="form-group">
                                                    <label for="recipient-name" class="control-label">邮箱</label>
                                                    <input type="email" class="form-control" id="recipient-name" name="email">
                                                </div>
                                                <div class="modal-footer">
                                                    <button type="submit" class="btn btn-primary">提交</button>
                                                </div>
                                            </form>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </td>
                    </tr>
                {% endif %}
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

{% block script_area %}
    <script>
        $(function () {
            $("tbody").on('click', '#del_publisher', function () {
                let $ele = $(this).parent().parent()
                $.ajax({
                    url: `/app03/publisher/del/${$(this).attr('publisher_id')}/`,
                    type: "post",
                    data: {
                        csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
                    },
                    success: function(response) {
                        response = JSON.parse(response)
                        if (response["status"] == true) {
                            $ele.remove()
                        } else {
                            alert('出版社删除失败!请重试')
                        }
                    }
                })
            })
        })
    </script>
{% endblock %}

项目心得总结

1、select多选框的实现方法

图片.png

name后一定要加[],不然接受到的就是一个值,而不是一个多选的列表!


图片.png

也不能再用get了,需要用getlist!获得的列表就可以直接*号打散传值!

2、删除书籍改用ajax发送请求(局部刷新)

<!--index.html文件的改变--> 
<!--随便在该文件任何地方添加一个模板标签csrf_token--> 
{% csrf_token %}

<!--下面的两个内容在对应地方修改或者添加即可!-->
<a id="del_book" class="btn btn-danger btn-xs" book_id={{ book_obj.pk }}>删除</a>

<script>
    $(function () {
        $("#del_book").click(function () {
            let $ele = $(this).parent().parent()
            $.ajax({
                url: `/books/del/${$(this).attr('book_id')}/`,
                type: "post",
                data: {
                    csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
                },
                success: function (response) {
                    response = JSON.parse(response)
/*
有人可能会纳闷,为什么这里就必须要在外面调用$ele,才能拿到$(this)
然而上面的url: `/books/del/${$(this).attr('book_id')}/`就不需要呢?
这个是在一个异步回调函数里,this指的是调用这个函数那个对象!
*/
                    if (response["status"]==true){
                        $ele.remove()
                    }else{
                        alert('书籍删除失败!请重试')
                    }
                }
            })
        })
    })
</script>
有人可能会纳闷,为什么这里就必须要在外面调用$ele,才能拿到$(this),然而上面的url: /books/del/${$(this).attr('book_id')}/就不需要呢?这个是在一个异步回调函数里,this指的是调用这个函数那个对象!
# 视图函数views.py的改变
def book_del(request, del_book_id):
    response = {'status': True}
    try:
        Book.objects.filter(pk=del_book_id).delete()
    except Exception:
        response['status'] = False
    return HttpResponse(json.dumps(response))

上面这种其实还是有缺陷的,click是事件绑定是吧,如果我添加书籍,那么新加书籍便不会绑定click事件!因此我们需要采用事件委托!

$("#del_book").click(function () {}
因此需要把上面这个代码改为:
$("tbody").on('click','#del_book',function () {}
# 释义:将click事件委托给tbody标签下的所有id为del_book的标签

这里发现出了点问题,采用事件绑定,新加书籍有些绑定了click事件,有些没绑定!这个不管,变成事件委托就妥妥的!

3、input框对手机号、年龄、email的输入限制方法

<input type="email"> # 提交表单时,如果没有@就会报错!

<input type="text" onkeyup="value=value.replace(/[^\d]/g,'')" maxlength="3" name="age">

onkeyup="" # 保证用户输入的只能是数字
maxlength="3" # 保证用户输入数字的长度,最多是三位数。手机号maxlength="11"即可

先把项目所用数据库准备好,改settings、__init__文件把数据库连接好!

4、设置url和视图函数映射关系

视图函数通过操作数据库,返回模板语法渲染好的页面,或者临时重定向到其他url对应的视图函数(我这里临时重定向的全是主页,因为数据修改完,就跳转到主页展示修改后的效果嘛)!

5、无论是模板中的html,还是视图函数都不要采用硬编码url,都应该使用name反向解析!


版权声明:本文转自CSDN博主「凤求凰的博客」的原创文章
原文链接:https://blog.csdn.net/weixin_44571270/article/details/107656213

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容