Python项目:基于 ORM 编写图书管理程序

展示所有图书信息、对图书可以进行增、删、改的操作。

1 结构关系

  • Author 表与 AuthorInfo 表为一对应关系。
  • Publisher 表与 Book 表为一对多关系。
  • Book 表与 Author 表为多对多关系。

2 创建项目

创建 mbookProject Django 项目,应用名称为 mbooks 。

2.1 配置 MySQL 数据库

# 1. 创建 mysql 数据库
mysql> create database ormdb CHARSET 'utf8';

# 2. mbookProject/__init__.py 中配置 Django 使用 pymysql 模块连接 MySQL 数据库:
import pymysql
pymysql.install_as_MySQLdb()

# 3. 修改 setting.py 中 DATABASES 配置如下
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'NAME': 'mbooksdb',
        'USER': 'root',
        'PASSWORD': 'toor',
    }
}

2.2 构建数据库表对象

# mbooks/models.py 下创建新表对象
from django.db import models

# Create your models here.
GENDERCHOICE = (
    ('M', 'Male'),
    ('F', 'Female'),
    ('U', 'Unknown'),
)

class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=12)
    gender = models.CharField(max_length=1, choices=GENDERCHOICE)
    age = models.IntegerField()

    authorinfo = models.OneToOneField(to='AuthorInfo', to_field='id', on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class AuthorInfo(models.Model):
    id = models.AutoField(primary_key=True)
    birthday = models.DateField()
    tel = models.IntegerField()
    add = models.CharField(max_length=64)

    def __str__(self):
        return self.add


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

    def __str__(self):
        return self.name


class Book(models.Model):
    name = models.CharField(max_length=32)
    publishDate = models.DateField()
    like = models.IntegerField(default=0)
    comment = models.IntegerField(default=0)
    share = models.IntegerField(default=0)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    publisher = models.ForeignKey(to='Publisher', to_field='id', on_delete=models.CASCADE)
    author = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name

    def get_author_name(self):
        # author_list = self.author.all()
        # author_name_list = [author.name for author in author_list]
        # ret = ','.join(author_name_list)
        # return ret
        return ','.join([author.name for author in self.author.all()])

2.3 创建表

# 在 Pycharm Terminal 下
python manage.py makemigrations
python manage.py migrate

2.4 创建 URLs

# 在 mbookProject/urls.py 下创建 url 路径
from django.contrib import admin
from django.urls import path,re_path
from mbooks import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/', views.home, name='home'),
    path('addbook/', views.addbook, name='addbook'),
    # 为了实现修改与删除的功能,利用书籍在数据库中的 ID 确定所要进行修改或删除的书籍,因此 url 需要传递两个参数
    re_path(r'editbook/(\d+)/', views.editbook, name='editbook'),
    re_path(r'delbook/(\d+)', views.delbook, name='delbook'),
]


2.5 创建图书展示界面

# mbooks/views.py 下
from django.shortcuts import render, HttpResponse,redirect
from mbooks import models


# Create your views here.

def home(request):
    all_books = models.Book.objects.all()

    return render(request, 'home.html', {'all_books': all_books})


def addbook(request):
    all_publisher = models.Publisher.objects.all()
    all_author = models.Author.objects.all()
    if request.method == 'POST':
        # 方式一
        bookName = request.POST.get('bookName')
        price = request.POST.get('price')
        publishDate = request.POST.get('publishDate')
        publisher = request.POST.get('publisher')
        author = request.POST.getlist('author')
        print(author)
        new_book = models.Book.objects.create(
            name = bookName,
            price = price,
            publishDate = publishDate,
            publisher_id = publisher,
        )
        new_book.author.add(*author)
        # # 方式二 若 html 文档中的name属性与数据库中的数据一致,可在去除无用数据后直接写成以下格式。      
        all_data = request.POST.dict()
        del all_data['csrfmiddlewaretoken']
        del all_data['author']
        print(all_data)
        new_book = models.Book.objects.create(
            **all_data
            # * 本质是一个tuple
            # ** 本质上是一个dict
        )
        return HttpResponse('added success!')

    else:
        return render(request, 'addbook.html', {'all_publisher': all_publisher, 'all_author': all_author})


def editbook(request, book_id):
    book_obj = models.Book.objects.filter(id=book_id)
    publisher_obj = models.Publisher.objects.all()
    author_obj = models.Author.objects.all()
    if request.method == 'POST':
        bookName = request.POST.get('bookName')
        price = request.POST.get('price')
        publishDate = request.POST.get('publishDate')
        publisher = request.POST.get('publisher')
        author = request.POST.getlist('author')
        print(author)
        book_obj.update(
            name = bookName,
            price = price,
            publishDate = publishDate,
            publisher_id = publisher,
        )
        book_obj.first().author.set(author)
        return redirect('home')
    else:
        book_obj = book_obj.first()
        return render(request, 'editbook.html', {'book_obj': book_obj, 'publisher_obj': publisher_obj,'author_obj':author_obj})


def delbook(request,book_id):
    models.Book.objects.filter(id=book_id).delete()
    return redirect('home')

2.6 创建模板文档

2.6.1 配置引用 static 静态文件

# setting.py 中末尾增加
STATICFILES_DIRS = [
    BASE_DIR / 'statics',
]

2.6.2 home.html

{% load static %}
<!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">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>home</title>
    <link rel="stylesheet" href="{% static '/bootstrap-3.3.7-dist/css/bootstrap.css' %}">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <!-- Default panel contents -->
                <div class="panel-heading">书籍展示</div>
                <div class="panel-body">
                    <div>
                        <a href="{% url 'addbook' %}" class="btn btn-success">添加书籍</a>
                    </div>


                    <!-- Table -->
                    <table class="table table-striped table-hover">
                        <thead>
                        <tr>
                            <th>编号</th>
                            <th>书籍名称</th>
                            <th>出版日期</th>
                            <th>点赞</th>
                            <th>评论</th>
                            <th>分享</th>
                            <th>价格</th>
                            <th>出版社</th>
                            <th>作者</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for book in all_books %}
                            <tr>
                                <td>{{ forloop.counter }}</td>
                                <td>{{ book.name }}</td>
                                <td>{{ book.publishDate|date:'Y-m-d' }}</td>
                                <td>{{ book.like }}</td>
                                <td>{{ book.comment }}</td>
                                <td>{{ book.share }}</td>
                                <td>{{ book.price }}</td>
                                <td>{{ book.publisher }}</td>
{#                                <td>#}
{#                                    {% for author in book.author.all %}#}
{#                                    {{ author.name }}#}
{#                                        {% if forloop.last %}#}
{#                                            {% else %}#}
{#                                            ,#}
{#                                        {% endif %}#}
{#                                    {% endfor %}#}
{#                                </td>#}
{#                                <td>{{ book.author.all }}</td>#}
                            <td>{{ book.get_author_name }}</td>
                            <td>
                                <a href="{% url 'editbook' book.id %}" class="btn btn-warning btn-sm">编辑</a>
                                <a href="{% url 'delbook' book.pk %}" class="btn btn-danger btn-sm">删除</a>
                            </td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

2.6.3 addbook.html

{% load static %}
<!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">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>addbook</title>
    <link rel="stylesheet" href="{% static '/bootstrap-3.3.7-dist/css/bootstrap.css' %}">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <form action="{% url 'addbook' %}" method="post" novalidate>
                {% csrf_token %}
                <div class="form-group">
                    <label for="bookName">书籍名称</label>
                    <input type="text" class="form-control" id="bookName" placeholder="书名" name="bookName">
                </div>
                <div class="form-group">
                    <label for="price">价格</label>
                    <input type="number" class="form-control" id="price" placeholder="价格" name="price">
                </div>
                <div class="form-group">
                    <label for="publishDate">出版日期</label>
                    <input type="date" class="form-control" id="publishDate" placeholder="日期" name="publishDate">
                </div>
                <div class="form-group">
                    <label for="publisher">出版社</label>
                    <select name="publisher" id="publisher" class="form-control">
                        {% for publisher in all_publisher %}
                            <option value="{{ publisher.id }}">{{ publisher.name }}</option>
                        {% endfor %}
                    </select>
                </div>
                <div class="form-group">
                    <label for="author">作者</label>
                    <select name="author" id="author" multiple class="form-control">
                        {% for author in all_author %}
                            <option value="{{ author.id }}">{{ author.name }}</option>
                        {% endfor %}

                    </select>
                </div>
                <button class="btn btn-success pull-right">提交</button>
            </form>

        </div>
    </div>

</div>
</body>
</html>

2.6.4 editbook.html

{% load static %}
<!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">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>editbook</title>
    <link rel="stylesheet" href="{% static '/bootstrap-3.3.7-dist/css/bootstrap.css' %}">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                <div class="form-group">
                    <label for="bookName">书籍名称</label>
                    <input type="text" class="form-control" id="bookName" placeholder="书名" name="bookName"
                           value="{{ book_obj.name }}">
                </div>
                <div class="form-group">
                    <label for="price">价格</label>
                    <input type="number" class="form-control" id="price" placeholder="价格" name="price"
                           value="{{ book_obj.price }}">
                </div>
                <div class="form-group">
                    <label for="publishDate">出版日期</label>
                    <input type="date" class="form-control" id="publishDate" placeholder="日期" name="publishDate"
                           value="{{ book_obj.publishDate|date:'Y-m-d' }}">
                </div>
                <div class="form-group">
                    <label for="publisher">出版社</label>
                    <select name="publisher" id="publisher" class="form-control">
                        {% for publisher in publisher_obj %}
                            {% if publisher.pk == book_obj.publisher.pk %}
                                <option value="{{ publisher.pk }}" selected>{{ publisher.name }}</option>
                            {% else %}
                                <option value="{{ publisher.pk }}"> {{ publisher.name }}</option>
                            {% endif %}
                        {% endfor %}
                    </select>
                </div>
                <div class="form-group">
                    <label for="author">作者</label>
                    <select name="author" id="author" multiple class="form-control">
                        {% for author in author_obj %}
                            {% if author in book_obj.author.all %}
                                <option value="{{ author.id }}" selected>{{ author.name }}</option>
                            {% else %}
                                <option value="{{ author.id }}">{{ author.name }}</option>

                            {% endif %}
                        {% endfor %}

                    </select>
                </div>
                <button class="btn btn-success pull-right">提交</button>
            </form>

        </div>
    </div>

</div>
</body>
</html>
posted @ 2021-03-19 08:55  f_carey  阅读(17)  评论(0)    收藏  举报  来源