样式有的没有改,总体功能实现了,一般小丑
项目名:day 67 Library Manager
APP名: APP01
项目文件夹下:
setting设置:

"""
Django settings for day67LibraryManager project.
Generated by 'django-admin startproject' using Django 1.11.15.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '27k2n&3&b@@^pmoddfjf&n__a=dq*rnr0r^l$lic4r(g@_13ii'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
# 'app02.apps.App02Config',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'day67LibraryManager.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'day67LibraryManager.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'library',
'USER':'root',
'PASSWORD':'liangshuang12',
'HOST':'127.0.0.1',
'PORT':3306,
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
]
# TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
__init__:

import pymysql pymysql.install_as_MySQLdb()
app01下:
models.py:

from django.db import models
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, unique=True)
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32, unique=True)
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
def __repr__(self):
return "<Book object: {} >".format(self.title)
class Author(models.Model):
name = models.CharField(max_length=32, unique=True)
books = models.ManyToManyField('Book')
def __repr__(self):
return "<Author object: {} >".format(self.name)
__str__ = __repr__
# from django.db import models
#
# # Create your models here.
#
# #出版社
# class Publisher(models.Model):
# id = models.AutoField(primary_key=True)
# name = models.CharField(max_length=32,unique=True)
#
# # def __str__(self):
# # return self.name
#
#
# #书
# class Book(models.Model):
# id = models.AutoField(primary_key = True)
# title = models.CharField(max_length=32,unique=True)
# Publisher = models.ForeignKey(to=Publisher,on_delete=models.CASCADE)
# def __repr__(self):
# return "<Boot object : {}>".format(self.title)
#
# #作者
#
# class Author(models.Model):
# name = models.CharField(max_length=32, unique=True)
# books = models.ManyToManyField('Book')
#
# def __repr__(self):
# return "<Author object: {}>".format(self.name)
#
# __str__ = __repr__
项目下.urls.py

"""day67LibraryManager URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
#出版社
url(r'^admin/', admin.site.urls),
url(r'del_(publisher|book|author)/(\d+)',views.delete),
url(r'^publisher/',views.publisher_list,name='publisher'), #路径,函数名
# 添加
# url(r'^add_publisher/',views.add_publisher),
url(r'add_publisher/',views.AddPublisher.as_view()),
# url(r'^add_publisher/',view),# 上面的AddPublisher.as_view()相当于view函数
#删除
url(r'^del_publisher/(\d+)/',views.del_publisher),
# 编辑
url(r'^edit_publisher/',views.edit_publisher),
# 书籍
url(r'^book_list/',views.book_list,name='book'), #书籍表格
url(r'^add_book/',views.add_book), #增加书籍
url(r'^del_book/(\d+)/',views.del_book), #删除书籍
url(r'^edit_book/',views.edit_book), #编辑书籍
#作者
url(r'^author_list/',views.author_list,name='author'), #作者列表
url(r'^add_author/',views.add_author), #添加
url(r'^del_author/(\d+)/',views.del_author), #删除
url(r'^edit_author/',views.edit_author), #编辑
#测试
# url(r'^test/',views.test)
# url(r'app01/' , include('app01.urls',namespace='app01')),
# url(r'app02/' , include('app02.urls',namespace='app02')),
#
# url(r'^tests/', views.tests)
]
app01下:views.py:

from django.shortcuts import render,HttpResponse,redirect,reverse
from app01 import models
from django.views import View
import time
def wapper(func):
def inner(*args,**kwargs):
start = time.time()
ret = func(*args,**kwargs)
print('函数执行的时间是:{}'.format(time.time()-start))
return ret
return inner
def publisher_list(request):
# 从数据库中获取所有的数据:
publisher_obj_list = models.Publisher.objects.all().order_by('-id')
return render(request,'publisher_list.html',{'publishers':publisher_obj_list})
# 添加出版社
@wapper
def add_publisher(request):
add_name,err_msg = '',''
if request.method=='POST':
add_name = request.POST.get('new_name')
pub_list = models.Publisher.objects.filter(name=add_name)
if add_name and not pub_list:
models.Publisher.objects.create(name=add_name)
return redirect('/publisher/')
if not add_name:
err_msg='不能为空'
if pub_list:
err_msg='出版社已存在'
return render(request,'add_publisher.html',{'err_name':add_name,'err_msg':err_msg})
#为函数加装饰器
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(wapper, name='post')
@method_decorator(wapper, name='get')
class AddPublisher(View):
def dispatch(self, request, *args, **kwargs):
print('执行get方法之前')
ret = super().dispatch(request,*args,**kwargs)
print('执行get方法之后')
return ret
def get(self,request):
# print('这个是get')
return render(self.request,'add_publisher.html')
def post(self,request):
print('这个是post')
err_msg = ''
add_name = request.POST.get('new_name')
pub_list = models.Publisher.objects.filter(name=add_name)
if add_name and not pub_list:
models.Publisher.objects.create(name=add_name)
return redirect('/publisher/')
if not add_name:
err_msg = '不能为空'
if pub_list:
err_msg = '出版社已存在'
return render(request, 'add_publisher.html', {"err_name": add_name, 'err_msg': err_msg})
# 添加出版社
# def add_publisher(request):
# if request.method == 'POST': #选择提交方式
# add_name = request.POST.get('new_name') #获取新添加的名字赋值给add_name
# if not add_name: #如果名字不存在为空
# return render(request, 'add_publisher.html', {"err_name": add_name, 'err_msg': '不能为空'})
# pub_list = models.Publisher.objects.filter(name=add_name) #过滤添加的name在不在Publisher表里
# if pub_list: # 如果存在表里
# return render(request, 'add_publisher.html',{"err_name":add_name,'err_msg':'出版社已存在'})
# models.Publisher.objects.create(name=add_name) #创建新内容(相当于前面有个else,函数遇见return结束函数,所以不用写else,如果没有return ,必须写else)
# return redirect('/publisher/') #返回跳转页面
# return render(request,'add_publisher.html')
#
#删除出版社
def del_publisher(request):
#获取要删除的对象id
del_id = request.GET.get('id')
del_list = models.Publisher.objects.filter(id=del_id)#筛选删除的id在Publisher里
if del_list:
#删除满足条件的所有对象
del_list.delete()
return redirect('/publisher/')
else:
return HttpResponse('删除失败')
#编辑出版社
def edit_publisher(request):
#获取要编辑的对象id
edit_id = request.GET.get('id')
edit_list = models.Publisher.objects.filter(id=edit_id)#筛选要编辑的id在Publisher里赋值给左边
err_msg = ''
if request.method == 'POST':
edit_name = request.POST.get('new_name')#获得输入新的出版社的名字
print(edit_name,type(edit_name))
check_list = models.Publisher.objects.filter(name=edit_name)#判断在不在原来的表里
if edit_name and edit_list and not check_list:
edit_obj = edit_list[0]
edit_obj.name = edit_name #新的出版社赋值给要编辑的出版社
edit_obj.save() # 保存在数据库中
return redirect('/publisher/')
if check_list:
err_msg = '出版社已存在'
if not edit_name:
err_msg = '出版社不能为空'
if edit_list:
edit_obj = edit_list[0] #从表里获取的
return render(request,'edit_publisher.html',{'old_obj':edit_obj,'err_msg':err_msg})
else:
return HttpResponse('数据不存在')
#书
def book_list(request):
books = models.Book.objects.all() #获取所有的书籍对象
return render(request,'book_list.html',{'books':books})
#增加书
def add_book(request):
if request.method == 'POST':
# 获取form表单提交的数据
book_name = request.POST.get('book_name') #添加的新名字
pub_id = request.POST.get('pub_id') #出版社的id
# pub_obj = models.Publisher.objects.get(id=pub_id)
# models.Book.objects.create(title=book_name,publisher=pub_obj)
models.Book.objects.create(title=book_name,publisher_id=pub_id) #添加书名出版社
return redirect('/book_list/') #跳转书籍表格页面
# 获取所有出版社信息
publisher_list = models.Publisher.objects.all()
return render(request,'add_book.html',{'publisher_list':publisher_list})
# 删除书
def del_book(request):
del_id = request.GET.get('book_id')
models.Book.objects.get(id=del_id).delete()
return redirect('/book_list/')
#编辑书籍
def edit_book(request):
if request.method == 'POST':
old_id = request.POST.get('old_id')
new_title = request.POST.get('new_title')
pub_id = request.POST.get('pub_id')
old_obj = models.Book.objects.get(id=old_id)
old_obj.title=new_title
old_obj.publisher_id = pub_id
# old_obj.publisher = models.Publisher.objects.get(id=pub_id)
old_obj.save()
return redirect('/book_list/')
edit_id = request.GET.get('id')
edit_obj = models.Book.objects.get(id=edit_id)
all_pub = models.Publisher.objects.all()
return render(request,'edit_book.html',{'edit_obj': edit_obj,'all_pub': all_pub})
#作者
def author_list(request):
author_list = models.Author.objects.all().order_by('id') #获取所有作者
return render(request,'author_list.html',{'author_list':author_list})
#增加作者
def add_author(request):
if request.method == 'POST':
author_name = request.POST.get('author_name')
book_ids = request.POST.getlist('book_ids')
author_obj = models.Author.objects.create(name=author_name)
author_obj.books.set(book_ids)
return redirect('/author_list/')
book_list = models.Book.objects.all()
return render(request,'add_author.html',{'book_list':book_list})
# #删除作者
def del_author(request):
del_id = request.GET.get('id')
models.Author.objects.get(id=del_id).delete()
#获取到作者对象
#在数据库中删除作者的数据
#删除多对多关系的记录
return redirect('/author_list/')
#
# #编辑
def edit_author(request):
edit_id = request.GET.get('id')
edit_obj = models.Author.objects.get(id=edit_id)
if request.method == 'POST':
new_author = request.POST.get('new_author')
book_ids = request.POST.getlist('book_ids')
edit_obj.name = new_author
edit_obj.save()
edit_obj.books.set(book_ids)
return redirect('/author_list/')
all_books = models.Book.objects.all()
return render(request,'edit_author.html', {'edit_obj':edit_obj,'all_books':all_books})
#l例题
def home(request,*args,**kwargs):
print(reverse('home',kwargs={'year':'1998','month':'23'}))
return HttpResponse('这个是app01book')
def tests(request):
print(reverse('app01:home',args=('1998','23')))
return render(request,'test.html')
#删除多个
def delete(request,table,del_id):
table_dict = {
'publisher':models.Publisher,
'book':models.Book,
'author':models.Author,
}
print(models.Book)
#方法一
# table_class = table_dict.get(table)
# 方法二:
table_class = getattr(models,table.capitalize())
print(table_class )
table_class.objects.get(id=del_id).delete()
return redirect(reverse(table))
templates:

{% extends 'base.html' %}
{% block name_t %}出版社{% endblock %}
{% block page-mian %}
<div class="row">
<div class="col-lg-3">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn"><button class="btn btn-default"
type="button">Go</button></span>
</div>
</div>
<div class="pull-right col-lg-3">
<a class="btn btn-info" href="/add_publisher/">添加出版社</a>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>出版社名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for publisher in publishers %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ publisher.id }}</td>
<td>{{ publisher.name }}</td>
<td>
<a class="btn btn-danger btn-sm" href="/del_publisher/{{ publisher.id }}/">
<i class="fa fa-trash fa-fw"></i>删除
</a>
<a class="btn btn-warning btn-sm" href="/edit_publisher/?id={{ publisher.id }}">
<i class="fa fa-edit fa-fw"></i>编辑
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" style="text-align: center">没有数据</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{# </div>#}
{# </div>#}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加出版社</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
{% include 'nav.html' %}
<div class="container" style="margin-top: 70px">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加出版社</h3>
</div>
<div class="panel-body">
<form class="form-horizontal" method="post" action="">
{% csrf_token %}
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputName" name="new_name"
value="{{ old_obj.name }}">
</div>
</div>
<p class="text-center text-danger">{{ err_msg }}</p>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑出版社</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
{#<h1>编辑出版社</h1>#}
{#<form action="" method="post">#}
{# <p>名称:<input type="text" name="new_name" value="{{ old_obj.name }}"></p><span>{{ err_msg }}</span>#}
{# <button>提交</button>#}
{#</form>#}
<div class="container" style="margin-top: 30px">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">编辑出版社</h3>
</div>
<div class="panel-body">
<form class="form-horizontal" method="post" action="">
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputName" name="new_name"
value="{{ old_obj.name }}">
</div>
</div>
<p class="text-center text-danger">{{ err_msg }}</p>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

{% extends 'base.html' %}
{% block pub_active %}
{% endblock %}
{% block book_active %}
active
{% endblock %}
{% block name_t %}书籍{% endblock %}
{% block page-mian %}
<div class="row">
<div class="col-lg-3">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn"><button class="btn btn-default"
type="button">Go</button></span>
</div>
</div>
<div class="pull-right col-lg-3">
<a class="btn btn-info" href="/add_book/">添加书籍</a>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>书名</th>
<th>出版社</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
<td>{{ book.publisher.name }}</td>
<td>
<a class="btn btn-danger btn-sm" href="/del_book/{{ book.id }}/">
删除
</a>
<a class="btn btn-warning btn-sm" href="/edit_book/?id={{ book.id }}">
编辑
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书籍列表</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
{% include 'nav.html' %}
<div class="container" style="margin-top: 70px">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加书籍</h3>
</div>
<div class="panel-body">
<form class="form-horizontal" method="post" action="">
{% csrf_token %}
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputName" name="book_name"
value="">
</div>
<div>
<label for="inputName" class="col-sm-2 control-label">出版社:</label>
<select name="pub_id" id="" class="control-label">
{% for pub in publisher_list %}
<option value="{{ pub.id }}">{{ pub.name }}</option>
{% endfor %}
</select>
</div>
</div>
<p class="text-center text-danger">{{ err_msg }}</p>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑书籍</title>
</head>
<body>
<h1>编辑书籍</h1>
<form action="" method="post">
<input type="text" name="old_id" value="{{ edit_obj.id }}" style="display: none">
<div>
书名:
<input type="text" name="new_title" value="{{ edit_obj.title }}">
</div>
<div>
出版社:
<select name="pub_id" id="">
{% for pub in all_pub %}
{% if pub.id == edit_obj.publisher_id %}
<option selected value="{{ pub.id }}">{{ pub.name }}</option>
{% else %}
<option value="{{ pub.id }}">{{ pub.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button>提交</button>
</form>
</body>
</html>

{% extends 'base.html' %}
{% block pub_active %}
{% endblock %}
{% block book_active %}
active
{% endblock %}
{% block name_t %}作者{% endblock %}
{% block page-mian %}
<div class="row">
<div class="col-lg-3">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn"><button class="btn btn-default"
type="button">Go</button></span>
</div>
</div>
<div class="pull-right col-lg-3">
<a class="btn btn-info" href="/add_author/">添加作者</a>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>作者名</th>
<th>著作</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for author in author_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author.id }}</td>
<td>{{ author.name }}</td>
<td>
{% for bok in author.books.all %}
{{ bok.title }}
{% endfor %}</td>
<td>
<a class="btn btn-danger btn-sm" href="/del_book/{{ author.id }}/">
删除
</a>
<a class="btn btn-warning btn-sm" href="/edit_book/?id={{ author.id }}">
编辑
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{#<!DOCTYPE html>#}
{#<html lang="en">#}
{#<head>#}
{# <meta charset="UTF-8">#}
{# <title>作者列表</title>#}
{#</head>#}
{#<body>#}
{#<a href="/add_author/">添加出版社</a>#}
{#<table border="1">#}
{# <thead>#}
{# <tr>#}
{# <th>序号</th>#}
{# <th>ID</th>#}
{# <th>作者</th>#}
{# <th>著作</th>#}
{# <th>操作</th>#}
{# </tr>#}
{# </thead>#}
{# <tbody>#}
{# {% for author in author_list %}#}
{# <tr>#}
{# <td>{{ forloop.counter }}</td>#}
{# <td>{{ author.id }}</td>#}
{# <td>{{ author.name }}</td>#}
{# <td>#}
{# {% for book in author.books.all %}#}
{# {% if forloop.last %}#}
{# 《{{ book.title }}》#}
{# {% else %}#}
{# 《{{ book.title }}》、#}
{# {% endif %}#}
{# {% endfor %}#}
{# </td>#}
{# <td>#}
{# <a href="/del_author/?id={{ author.id }}"><button>删除</button></a>#}
{# <a href="/edit_author/?id={{ author.id }}"><button>编辑</button></a>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
{# </tbody>#}
{#</table>#}
{#</body>#}
{#</html>#}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加作者</title>
</head>
<body>
<form action="" method = 'post'>
<div>
作者名字:
<input type="text" name="author_name">
</div>
<div>
作品:
<select name="book_ids" id="" multiple>
{% for book in book_list %}
<option value="{{ book.id }}">{{ book.title }}</option>
{% endfor %}
</select>
</div>
<button type="submit">提交</button>
</form>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑作者</title>
</head>
<body>
<h1>编辑作者</h1>
<form action="" method="post">
<div>
作者名:
<input type="text" name="new_author" value="{{ edit_obj.name }}">
</div>
<div>
著作:
<select name="book_ids" id="" multiple>
{% for book in all_books %}
{% if book in edit_obj.books.all %}
<option value="{{ book.id }}" selected>{{ book.title }}</option>
{% else %}
<option value="{{ book.id }}">{{ book.title }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button type="submit">提交</button>
</form>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css">
<link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="/static/css/pub.css">
</head>
<body>
{#导入标题组件#}
{% include 'nav.html' %}
{#如果不导入显示以下标题代码 导入的代替了下面代码#}
{#<nav class="navbar navbar-inverse navbar-fixed-top">#}
{# <div class="container-fluid">#}
{# <div class="navbar-header">#}
{# <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"#}
{# aria-expanded="false" aria-controls="navbar">#}
{# <span class="sr-only">Toggle navigation</span>#}
{# <span class="icon-bar"></span>#}
{# <span class="icon-bar"></span>#}
{# <span class="icon-bar"></span>#}
{# </button>#}
{# <a class="navbar-brand" href="#">图书管理系统</a>#}
{# </div>#}
{# <div id="navbar" class="navbar-collapse collapse">#}
{# <ul class="nav navbar-nav navbar-right">#}
{# <li><a href="#">Dashboard</a></li>#}
{# <li><a href="#">Settings</a></li>#}
{# <li><a href="#">Profile</a></li>#}
{# <li><a href="#">Help</a></li>#}
{# </ul>#}
{# <form class="navbar-form navbar-right">#}
{# <input type="text" class="form-control" placeholder="Search...">#}
{# </form>#}
{# </div>#}
{# </div>#}
{#</nav>#}
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="{% block pub_active %}active{% endblock %}"><a href="/publisher/">出版社管理 <span
class="sr-only">(current)</span></a></li>
<li class="{% block book_active %}{% endblock %}"><a href="/book_list/">书籍管理</a></li>
<li class="{% block author_active %}{% endblock %}"><a href="/author_list/">作者管理</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
{# 创建块,在子页面中块内的内容会被覆盖#}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{% block name_t %} {% endblock %}列表</h3>
</div>
<div class="panel-body">
{% block page-mian %}
{% endblock %}
{% load mytags %}
{% pagination 10 5 %}
</div>
</div>
</div>
</div>
</div>
</body>
</html>

<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统-s13</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>

<div class="text-center">
<nav aria-label="...">
<ul class="pagination">
<li class="disabled"><a href="#" aria-label="Previous"><span
aria-hidden="true">«</span></a>
</li>
{% for num in total %}
{% if num == current %}
<li class="active"><a href="#">{{ num }}</a></li>
{% else %}
<li><a href="#">{{ num }}</a></li>
{% endif %}
{% endfor %}
<li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li>
</ul>
</nav>
</div>
如果需要继承就要用到,母板,导航栏,组件,不需要继承就不用
static文件夹下css下:(css,可能有多余的文件)
log.css:

body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
style.css:

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,dl,dt,dd,ol,nav ul,nav li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}ol,ul{list-style:none;padding:0;margin:0}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}a{text-decoration:none}.txt-rt{text-align:right}.txt-lt{text-align:left}.txt-center{text-align:center}.float-rt{float:right}.float-lt{float:left}.clear{clear:both}.pos-relative{position:relative}.pos-absolute{position:absolute}.vertical-base{vertical-align:baseline}.vertical-top{vertical-align:top}.underline{padding-bottom:3px;border-bottom:1px solid #eee}nav.vertical ul li{display:block}nav.horizontal ul li{display:inline-block}img{max-width:100%}body{font-family:roboto,sans-serif;text-align:center;background:url(../images/background.png);background-repeat:no-repeat;background-attachment:fixed;background-position:center;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover}body a{transition:.5s all;-webkit-transition:.5s all;-moz-transition:.5s all;-o-transition:.5s all;-ms-transition:.5s all;text-decoration:none}h1{font-size:45px;font-weight:500;letter-spacing:4px;margin:60px 0;color:#fff}.container{width:50%;margin:0 auto;padding:40px;background-color:rgba(10,10,10,.77);border:2px ridge rgba(238,238,238,.13);border-radius:5px;-moz-box-shadow:0 -5px 10px 1px rgba(16,16,16,.57);-webkit-box-shadow:0 -5px 10px 1px rgba(16,16,16,.57);box-shadow:0 -5px 10px 1px rgba(16,16,16,.57);border-bottom:0;border-bottom-left-radius:initial;border-bottom-right-radius:initial}.login{width:45%;float:left;text-align:left;padding-right:40px}::-webkit-input-placeholder{color:#ccc}:-moz-placeholder{color:#ccc}::-moz-placeholder{color:#ccc}:-ms-input-placeholder{color:#ccc}h2{font-size:35px;text-align:left;color:#fff;font-weight:100;margin-bottom:20px}ul.tick{float:left;list-style:none;display:inline-block;width:100%;margin-bottom:20px}ul.tick li input[type=checkbox]{display:none}ul.tick li input[type=checkbox]+label{position:relative;padding-left:30px;border:#f0f8ff;display:inline-block;font-size:13px;color:#eee}ul.tick li input[type=checkbox]+label span:first-child{width:17px;height:17px;display:inline-block;border:1px solid #eee;position:absolute;top:-3px;left:0;bottom:4px}ul.tick li input[type=checkbox]:checked+label span:first-child:before{content:"";background:url(../images/tick.png)no-repeat;position:absolute;left:3px;top:3px;font-size:10px;width:10px;height:10px}.social-icons{margin-top:20px;text-align:center}.social-icons p{color:#ccc;margin-bottom:15px}.social-icons ul li{float:left;width:32.9%}.copyrights{text-indent:-9999px;height:0;line-height:0;font-size:0;overflow:hidden}li.twt{margin:0 2px}.social-icons ul li a{display:block}.social-icons ul li a span{vertical-align:middle;color:#fff;font-size:15px}.social-icons ul li span.icons{background:url(../images/i1.png) no-repeat center;width:30px;height:30px;display:inline-block}.social-icons ul li.weixin span.icons{background:url(../images/weixin.png) no-repeat;background-size:100%}.social-icons ul li.qq span.icons{background:url(../images/QQ.png) no-repeat;background-size:100%}.social-icons ul li.weibo span.icons{background:url(../images/weibo.png) no-repeat;background-size:100%}.social-icons ul li a:hover span.icons{transform:rotatey(360deg);-webkit-transform:rotatey(360deg);-o-transform:rotatey(360deg);-moz-transform:rotatey(360deg);-ms-transform:rotatey(360deg);transition:.5s all}input[type=text],input[type=password]{width:93.4%;margin-bottom:20px;padding:10px;float:left;background-color:transparent;border:0;font-size:15px;border-bottom:1px solid rgba(238,238,238,.41);outline:0;color:#fff}.send-button{margin-bottom:20px}.send-button input[type=submit]{width:60%;padding:10px 0;font-size:16px;font-weight:100;background-color:transparent;color:#ccc;border:1px solid rgba(238,238,238,.41);border-width:thin;cursor:pointer;outline:0;transition:.5s all;-webkit-transition:.5s all;-moz-transition:.5s all;-o-transition:.5s all;-ms-transition:.5s all;text-decoration:none}.send-button input[type=submit]:hover{background-color:#000;border:1px solid #fff;color:#fff;transition:.5s all;-webkit-transition:.5s all;-moz-transition:.5s all;-o-transition:.5s all;-ms-transition:.5s all;text-decoration:none}.login a{color:#ccc}.login a:hover{color:#fff}.register{width:44%;float:left;border-left:1px solid #ddd;padding-left:40px;text-align:left}.register p{color:#ccc;margin-bottom:10px}.register p a{color:#ccc}.register p a:hover{color:#fff}.footer{text-align:center;margin:100px 20px 20px}.footer p{color:#ccc;line-height:25px}.footer a{color:#ccc;text-decoration:none}.footer a:hover{color:#fff}@media screen and (max-width:1920px){h1{margin:100px 0}}@media screen and (max-width:1600px){h1{margin:60px 0}}@media screen and (max-width:1440px){.container{width:53%}}@media screen and (max-width:1366px){h1{margin:50px 0}.container{width:57%}}@media screen and (max-width:1280px){.container{width:60%}}@media screen and (max-width:1024px){.container{width:76%}}@media screen and (max-width:966px){.container{width:80%}.footer{margin:50px 20px 20px}}@media screen and (max-width:853px){.login{padding-right:36px}.register{padding-left:36px}.social-icons ul li{width:32.8%}.register p{font-size:14px}}@media screen and (max-width:800px){h1{font-size:43px}.login{padding-right:35px}.register{padding-left:34px}.social-icons ul li span.icons{width:28px}}@media screen and (max-width:768px){.container{width:85%}.register p{font-size:13.8px}}@media screen and (max-width:736px){h1{font-size:40px}.container{width:87%;padding:35px}.login{padding-right:34px}.register{padding-left:33px}.social-icons ul li a span{font-size:14px}.register p{font-size:13.2px}}@media screen and (max-width:667px){h1{font-size:35px;letter-spacing:3px}.container{width:55%;padding:50px}.login{padding:0;width:100%;margin-bottom:50px}.register{padding:40px 0 0;width:100%;border:0;border-top:1px solid #ddd}}@media screen and (max-width:603px){h1{letter-spacing:2px}}@media screen and (max-width:568px){h1{letter-spacing:1px;margin:30px 0}.container{width:60%;padding:40px}}@media screen and (max-width:533px){h1{font-size:32px}}@media screen and (max-width:480px){.container{width:70%;padding:35px}.send-button input[type=submit]{width:50%;padding:8px 0}}@media screen and (max-width:414px){h1{font-size:30px}.container{width:75%;padding:25px}.login{margin-bottom:30px}h2{font-size:30px;margin-bottom:15px}.register{padding:30px 0 0}.footer p{font-size:14px}}@media screen and (max-width:384px){h1{letter-spacing:0}}@media screen and (max-width:375px){.social-icons ul li span.icons{width:27px}.register p{font-size:13px;line-height:23px}}@media screen and (max-width:360px){.container{width:80%;padding:20px}}@media screen and (max-width:320px){.social-icons ul li{width:32.7%}.social-icons ul li span.icons{width:25px}.social-icons ul li a span{font-size:12.4px}}
pub.css:

/*
* Base structure
*/
/* Move down content because we have a fixed navbar that is 50px tall */
body {
padding-top: 50px;
}
/*
* Global add-ons
*/
.sub-header {
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
/*
* Top navigation
* Hide default border to remove 1px line.
*/
.navbar-fixed-top {
border: 0;
}
/*
* Sidebar
*/
/* Hide for mobile, show later */
.sidebar {
display: none;
}
@media (min-width: 768px) {
.sidebar {
position: fixed;
top: 51px;
bottom: 0;
left: 0;
z-index: 1000;
display: block;
padding: 20px;
overflow-x: hidden;
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
}
/* Sidebar navigation */
.nav-sidebar {
margin-right: -21px; /* 20px padding + 1px border */
margin-bottom: 20px;
margin-left: -20px;
}
.nav-sidebar > li > a {
padding-right: 20px;
padding-left: 20px;
}
.nav-sidebar > .active > a,
.nav-sidebar > .active > a:hover,
.nav-sidebar > .active > a:focus {
color: #fff;
background-color: #428bca;
}
/*
* Main content
*/
.main {
padding: 20px;
}
@media (min-width: 768px) {
.main {
padding-right: 40px;
padding-left: 40px;
}
}
.main .page-header {
margin-top: 0;
}
/*
* Placeholder dashboard ideas
*/
.placeholders {
margin-bottom: 30px;
text-align: center;
}
.placeholders h4 {
margin-bottom: 0;
}
.placeholder {
margin-bottom: 20px;
}
.placeholder img {
display: inline-block;
border-radius: 50%;
}
来源:https://www.cnblogs.com/ls13691357174/p/9646456.html
