Python项目:基于 ORM 编写图书管理程序
基于 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>

浙公网安备 33010602011771号