收藏网站

Django图书管理系统(增删改查)

2020年9月13日 20:04 Django 4830

用Django制作一个简单的图书管理软件,包含作者管理、出版社管理、图书管理三个功能。

# 开发环境

Python:3.80
Django:3.0.2
Pycharm:2019

创建项目(my_books)

创建django项目

创建APP

为了增强项目的可读性,我们将分别创建作者管理(author)、出版社管理(publish)、图书管理(book)三个APP。这里我们使用一个小技巧,创建一个apps目录,把所有APP应用都安装到这里,便于管理。

创建目录

然后apps目录上右键选择:Mark Directory as --> Sources Root

setting.py中添加以下代码:

# setting.py

import sys
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))

# 使用pycharm创建APP

python manage.py startapp author  # 创建作者应用
python manage.py startapp publish  # 创建出版社应用
python manage.py startapp book  # 创建图书应用

创建好的APP拖动到apps文件夹下(弹出对话框,取消勾选Search for references)

settings.py文件中找到INSTALLED_APPS并新增以下代码:

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 下面三个是新增的
    'author',
    'publish',
    'book',
]

django创建应用

URL路由

my_books目录下的urls.py为总路由引用(author、publish、book)下的urls.py文件。

# my_books下的urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),  # 后台管理
    path('author/',include('author.urls')),  # 作者管理
    path('publish/',include('publish.urls')),  # 出版社管理
    path('book/',include('book.urls')),  # 图书管理
]

然后在每个APP下面单独创建urls.py文件

创建python文件

前端模板(Template)

在templates目录下创建前端静态模板,用来接收或传递后端数据,base.html为父级文件。

显示所有作者:author_list.html、新增作者:author_add.html、修改作者:author_edit.html

显示所有出版社:publish_list.html、新增出版社:publish_add.html、编辑出版社:publish_edit.html

显示所有图书:book_list.html、新增图书:book_add.html、编辑图书:book_edit.html

# base.html 父级模板,其他模板将继承base.html

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
    {% block title %}<title>父级模板</title>{% endblock %}
    {% block keywords %}<meta name="keywords" content="" />{% endblock %}
    {% block description %}<meta name="description" content="" />{% endblock %}
    {% block css %}<link rel="stylesheet" type="text/css" href="/images/css/common.css" />{% endblock %}
</head>

<body>
    {% block nav %}
    <nav>
        <div class="container">
            <ul>
                <li><a href="{% url 'book' %}"><i></i>主页</a></li>
                <li><a href="{% url 'book' %}"><i></i>图书管理</a></li>
                <li><a href="{% url 'author' %}"><i></i>作者管理</a></li>
                <li><a href="{% url 'publish' %}"><i></i>出版社管理</a></li>
            </ul>
        </div>
    </nav>
    {% endblock %}
    <main>
        {% block content %}{% endblock %}
    </main>
    {% block footer %}
    <footer>
        <p>简单的图书管理系统,适合初学者作为项目练习,请勿用于实际生产</p>
        <p><span>技术支持:<a href="">极禾科技</a></span></p>
    </footer>
    {% endblock %}
</body>
</html>

创建前端模板

图书管理模板新增图书模板修改图书模板

作者管理功能

数据模型(Model):

# author目录下的models.py

from django.db import models


class Author(models.Model):
    """图书作者模型"""
    name = models.CharField('作者',max_length=32)
    mobile = models.CharField('电话',max_length=32)

    class Meta:
        verbose_name = '作者'
        verbose_name_plural = '图书作者'

    def __str__(self):
        return self.name

执行数据迁移:

# pycharm中依次执行下列命令

python manage.py makemigrations
python manage.py migrate

编写视图函数(View):

# author目录下的views.py

from django.shortcuts import render,redirect
from author.models import Author


def author_list(request):
    """作者管理"""
    authors = Author.objects.all()
    context = {
        'authors':authors,
    }
    return render(request,'author_list.html',context)


def author_add(request):
    """新增作者"""
    if request.method == 'POST':
        name = request.POST.get('name')
        mobile = request.POST.get('mobile')
        try:
            Author.objects.create(name=name,mobile=mobile)
            return redirect('/author/')
        except:
            error = '数据出错'
    return render(request,'author_add.html')


def author_edit(request,author_id):
    """修改作者"""
    authors = None
    if request.method == 'POST':
        name = request.POST.get('name')
        mobile = request.POST.get('mobile')
        # 第一种方式
        # authors.name = name
        # authors.mobile = mobile
        # authors.save()
        # 第二种方式
        try:
            Author.objects.filter(pk=author_id).update(name=name,mobile=mobile)
            return redirect('/author/')
        except:
            error = '修改失败'
    else:
        authors = Author.objects.get(pk=author_id)
    context = {
        'authors':authors,
    }
    return render(request,'author_edit.html',context)


def author_del(request,author_id):
    """删除作者"""
    author_list_del = Author.objects.filter(id=author_id).filter()
    if author_list_del:
        try:
            author_list_del.delete()
            return redirect('/author/')
        except:
            error = '删除失败'
    else:
        error = '作者删除失败'

    context = {
        'error':error,
    }
    return render(request, 'author_list.html', context)

作者APP路由设置:

# author目录下的urls.py

from django.urls import path
from author import views

urlpatterns = [
    path('',views.author_list,name='author'),  # 作者管理
    path('add/',views.author_add,name='author_add'),  # 新增作者
    path('edit/<int:author_id>',views.author_edit,name='author_edit'),  # 修改作者
    path('del/<int:author_id>',views.author_del,name='author_del'),  # 删除作者
]

模板文件(Template):

# author_list.html

{% extends 'base.html' %}
{% block title %}<title>作者管理</title>{% endblock %}
<main>
        {% block content %}
        <div class="search">
            <form action="" method="POST">
                <input type="text" name="search_text" placeholder="请出入搜索关键字">
                <button type="submit" class="search_btn">搜索</button>
            </form>
            <div class="add_btn">
                <a href="{% url 'author' %}add/">新增</a>
            </div>
        </div>
        <table>
            <thead>
                <tr>
                    <th>编号</th>
                    <th>作者</th>
                    <th>电话</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                {% for author in authors %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ author.name }}</td>
                    <td>{{ author.mobile }}</td>
                    <td><a href="{% url 'author' %}edit/{{ author.id }}">修改</a><a href="{% url 'author' %}del/{{ author.id }}">删除</a></td>
                </tr>
                {% empty %}
                    <tr><td>没有作者</td></tr>
                {% endfor %}
            </tbody>
        </table>
            {% if error %}
                <div class="error">{{ error }}</div>
            {% endif %}
        {% endblock %}
</main>
# author_add.htm

{% extends 'base.html' %}
{% block title %}<title>新增作者</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>新增作者</h2>
            {% csrf_token %}
            <p><input type="text" name="name" id="name" placeholder="姓名" autocomplete="off"><label for="name">请输入作者名字</label></p>
            <p><input type="text" name="mobile" id="mobile" placeholder="电话"><label for="mobile">请输入作者电话</label></p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
    {% endblock %}
</main>
# author_edit.html

{% extends 'base.html' %}
{% block title %}<title>修改作者</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>修改作者</h2>
            {% csrf_token %}
            <p><input type="text" name="name" id="name" placeholder="姓名" autocomplete="off" value="{{ authors.name }}"><label for="name">请输入作者名字</label></p>
            <p><input type="text" name="mobile" id="mobile" placeholder="电话" value="{{ authors.mobile }}"><label for="mobile">请输入作者电话</label></p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
    {% endblock %}

</main>

出版社管理功能

数据模型(Model):

# publish目录下的models.py

from django.db import models


class Publish(models.Model):
    """出版社模型"""
    name = models.CharField('出版社',max_length=32)
    mobile = models.CharField('电话',max_length=32)
    city = models.CharField('城市',max_length=32)

    def __str__(self):
        return self.name

执行数据迁移:

# pycharm中依次执行下列命令

python manage.py makemigrations
python manage.py migrate

编写视图函数(View):

# publish目录下的views.py

from django.shortcuts import render,redirect
from publish.models import Publish


def publish_list(request):
    """出版社管理"""
    publish_all = Publish.objects.all()
    context = {
        'publish_all':publish_all,
    }
    return render(request,'publish_list.html',context)


def publish_add(request):
    """新增出版社"""
    if request.method == 'POST':
        name = request.POST.get('name')
        city = request.POST.get('city')
        try:
            Publish.objects.create(name=name,city=city)
            return redirect('/publish/')
        except:
            error = '新增出版社失败'
    return render(request,'publish_add.html')


def publish_edit(request,publish_id):
    """修改出版社"""
    publish_edit_id = None
    if request.method == 'POST':
        name = request.POST.get('name')
        city = request.POST.get('city')
        try:
            Publish.objects.filter(id=publish_id).update(name=name,city=city)
            return redirect('/publish/')
        except:
            error = '修改失败'
    else:
        publish_edit_id = Publish.objects.filter(id=publish_id).first()

    context = {
        'publish_edit_id':publish_edit_id,
    }
    return render(request,'publish_edit.html',context)


def publish_del(request,publish_id):
    """删除出版社"""
    publish_del_list = Publish.objects.filter(id=publish_id).first()
    if publish_del_list:
        try:
            publish_del_list.delete()
            return redirect('/publish/')
        except:
            error = '删除失败'

    else:
        error = '删除失败'

    context = {
        'error':error,
    }
    return render(request, 'publish_list.html', context)

出版社管理路由设置:

# publish目录下的urls.py

from django.urls import path
from publish import views

urlpatterns = [
    path('',views.publish_list,name='publish'),  # 出版社管理
    path('add/',views.publish_add,name='publish_add'),  # 新增出版社
    path('edit/<int:publish_id>',views.publish_edit,name='publish_edit'),  # 修改出版社
    path('del/<int:publish_id>',views.publish_del,name='publish_del'),  # 删除出版社
]

模板文件(Template):

# publist_list.html

{% extends 'base.html' %}
{% block title %}<title>出版社管理</title>{% endblock %}
<main>
        {% block content %}
        <div class="search">
            <form accept="" method="POST">
                <input type="text" name="search_text" placeholder="请出入搜索关键字">
                <button type="submit" class="search_btn">搜索</button>
            </form>
            <div class="add_btn">
                <a href="{% url 'publish_add' %}">新增</a>
            </div>
        </div>
        <table>
            <thead>
                <tr>
                    <th>编号</th>
                    <th>出版社</th>
                    <th>城市</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
            {% for publish in publish_all %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ publish.name }}</td>
                    <td>{{ publish.city }}</td>
                    <td><a href="{% url 'publish' %}edit/{{ publish.id }}">修改</a><a href="{% url 'publish' %}del/{{ publish.id }}">删除</a></td>

                </tr>
                {% empty %}
                <tr><td>没有出版社</td></tr>
            {% endfor %}
            </tbody>
        </table>
            {% if error %}
                <div class="error">{{ error }}</div>
            {% endif %}
        {% endblock %}
</main>
# publist_add.html

{% extends 'base.html' %}
{% block title %}<title>新增出版社</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>新增出版社</h2>
            {% csrf_token %}
            <p><input type="text" name="name" id="name" placeholder="出版社" autocomplete="off"><label for="name">请输入出版社名称</label></p>
            <p><input type="text" name="city" id="city" placeholder="城市" autocomplete="off"><label for="city">请输入城市</label></p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
    {% endblock %}
</main>
# publist_edit.html

{% extends 'base.html' %}
{% block title %}<title>修改出版社</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>修改出版社</h2>
            {% csrf_token %}
            <p><input type="text" name="name" id="name" placeholder="出版社" autocomplete="off" value="{{ publish_edit_id.name }}"><label for="name">请输入出版社名称</label></p>
            <p><input type="text" name="city" id="city" placeholder="城市" autocomplete="off" value="{{ publish_edit_id.city }}"><label for="city">请输入城市</label></p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
    {% endblock %}
</main>

图书管理功能

数据模型(Model):

# book目录下的models.py

from django.db import models
from author.models import Author
from publish.models import Publish


class Book(models.Model):
    """图书模型"""
    title = models.CharField('图书',max_length=64)
    price = models.CharField('价格',max_length=32)
    pub_date = models.DateField('出版日期',auto_now_add=True)
    author = models.ManyToManyField('author.Author',verbose_name='作者')
    publish = models.ForeignKey('publish.Publish',verbose_name='出版社',on_delete=models.CASCADE)

    class Meta:
        verbose_name = '图书'
        verbose_name_plural = '图书管理'

    def __str__(self):
        return self.title

执行数据迁移:

# pycharm中依次执行下列命令

python manage.py makemigrations
python manage.py migrate

视图函数(View):

# book目录下的views.py

from django.shortcuts import render,redirect
from book.models import Book
from author.models import Author
from publish.models import Publish


def book_list(request):
    """图书管理"""
    book_all = Book.objects.all()
    context = {
        'book_all':book_all,
    }
    return render(request,'book_list.html',context)


def book_add(request):
    """新增图书"""
    error = ''
    author_all = Author.objects.all()  # 查询出所有作者,给前端使用
    publish_all = Publish.objects.all()  # 查询所有出版社
    if request.method == 'POST':
        title = request.POST.get('title')
        price = request.POST.get('price')
        author = request.POST.getlist('author')
        publish = request.POST.get('publish')
        if title == '' or price == '':
            error = '不能为空,请输入内容'
        else:
            book_add_list = Book.objects.create(title=title,price=price,publish_id=publish)
            # book和author是多对多关系,这里需要使用正向查询:按字段进行添加作者
            book_add_list.author.add(*author)
            return redirect('/book/')
    context = {
        'error':error,
        'author_all':author_all,
        'publish_all':publish_all,
    }
    return render(request,'book_add.html',context)


def book_edit(request,book_id):
    """修改图书"""
    author_all = Author.objects.all()  # 查询出所有作者,给前端使用
    publish_all = Publish.objects.all()  # 查询所有出版社

    book_edit_list = Book.objects.filter(id=book_id).first()
    # 基于前端传过来的ID查询出目前这本书的当前作者信息,编辑时把已选作者勾选上
    author_select = book_edit_list.author.all()
    if request.method == 'POST':
        title = request.POST.get('title')
        price = request.POST.get('price')
        author = set(request.POST.getlist('author'))
        publish = request.POST.get('publish')
        try:
            books_edit = Book.objects.filter(id=book_id).update(title=title,price=price,publish=publish)
            book_edit_list.author.set(author)
            return redirect('/book/')
        except:
            error = '修改失败'
    context = {
        'author_all': author_all,
        'publish_all': publish_all,
        'author_select':author_select,
        'book_edit_list':book_edit_list,
    }
    return render(request,'book_edit.html',context)


def book_del(request,book_id):
    """删除图书"""
    book_del_list = Book.objects.filter(id=book_id).first()
    if book_del_list:
        try:
            book_del_list.delete()
            return redirect('/book/')
        except:
            error = '删除失败'
    else:
        error = '删除失败'

    context = {
        'error':error,
    }
    return render(request, 'book_list.html',context)

图书管理路由设置:

# book目录下的urls.py

from django.urls import path
from book import views


urlpatterns = [
    path('',views.book_list,name='book'),  # 图书管理
    path('add/',views.book_add,name='book_add'),  # 新增图书
    path('edit/<int:book_id>',views.book_edit,name='book_edit'),  # 修改图书
    path('del/<int:book_id>',views.book_del,name='book_del'),  # 删除图书
]

模板文件(Template):

# book_list.html

{% extends 'base.html' %}
{% block title %}<title>图书管理</title>{% endblock %}
<main>
        {% block content %}
        <div class="search">
            <form accept="" method="POST">
                <span>类型:</span>
                <select>
                    <option value="全部">全部</option>
                    <option value="作者">作者</option>
                    <option value="出版社">出版社</option>
                </select>
                <input type="text" name="search_text" placeholder="请出入搜索关键字">
                <button type="submit" class="search_btn">搜索</button>
            </form>
            <div class="add_btn">
                <a href="{% url 'book_add' %}">新增</a>
            </div>
        </div>
        <table>
            <thead>
                <tr>
                    <th>编号</th>
                    <th>图书</th>
                    <th>价格</th>
                    <th>作者</th>
                    <th>出版社</th>
                    <th>出版日期</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
            {% for books in book_all %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ books.title }}</td>
                    <td>{{ books.price }}</td>
                    <td>{% for authors in books.author.all %}<a>{{ authors }}</a>{% endfor %}</td>
                    <td>{{ books.publish }}</td>
                    <td>{{ books.pub_date }}</td>
                    <td><a href="{% url 'book' %}edit/{{ books.id }}">修改</a><a href="{% url 'book' %}del/{{ books.id }}">删除</a></td>
                </tr>
                {% empty %}
                <tr><td>没有数据</td></tr>
                {% endfor %}
            </tbody>
        </table>
                    {% if error %}
                <div class="error">{{ error }}</div>
            {% endif %}
        {% endblock %}
</main>
# book_add.html

{% extends 'base.html' %}
{% block title %}<title>新增图书</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>新增图书</h2>
            {% csrf_token %}
            <p><input type="text" name="title" id="title" placeholder="图书名称" autocomplete="off"><label for="title">请输入图书名称</label></p>
            <p><input type="text" name="price" id="price" placeholder="价格"><label for="price">请输入价格</label></p>
            <p><select name="author" multiple="multiple">
                {% for author in author_all %}
                <option value="{{ author.id }}">{{ author.name }}</option>
                {% endfor %}
                </select>
                <label for="size">请选择作者</label>
            </p>
            <p><select name="publish">
                {% for publish in publish_all %}
                <option value="{{ publish.id }}">{{ publish.name }}</option>
                {% endfor %}
                </select>
                <label for="size">请选择出版社</label>
            </p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
        {% if error %}
            <div>{{ error }}</div>
        {% endif %}
    {% endblock %}
</main>
# book_edit.html


{% extends 'base.html' %}
{% block title %}<title>修改图书</title>{% endblock %}
<main>
    {% block content %}
        <form class="form1" action="" method="post">
            <h2>修改图书</h2>
            {% csrf_token %}
            <p><input type="text" name="title" id="title" placeholder="图书名称" autocomplete="off" value="{{ book_edit_list.title }}"><label for="title">请输入图书名称</label></p>
            <p><input type="text" name="price" id="price" placeholder="价格" value="{{ book_edit_list.price }}"><label for="price">请输入价格</label></p>
            <p><select name="author" multiple="multiple">
                {% for author_select in author_select %}
                <option value="{{ author_select.id }}" selected>{{ author_select.name }}</option>
                {% endfor %}
                {% for author in author_all %}
                <option value="{{ author.id }}">{{ author.name }}</option>
                {% endfor %}
                </select>
                <label for="author">请选择作者</label>
            </p>
            <p><select name="publish">
                <option value="{{ book_edit_list.publish.id }}" selected>{{ book_edit_list.publish.name }}</option>
                {% for publish in publish_all %}
                <option value="{{ publish.id }}">{{ publish.name }}</option>
                {% endfor %}
                </select>
                <label for="publish">请选择出版社</label>
            </p>
            <div class="button">
            <button type="submit" class="btn_save">保存</button>
            <a href="" class="btn_cancel">取消</a>
            </div>
        </form>
    {% endblock %}
</main>

未完待续(抽空写代码注释)

热点推荐

扫码添加微信