好好吃飯 按時(shí)睡覺(jué) 不要抱怨 心懷善念 堅(jiān)持做自己喜歡做的事 用心感受生活的每一個(gè)細(xì)節(jié) 沉淀 再沉淀 因?yàn)槟阋蔀橐粋€(gè)溫柔而強(qiáng)大的人
一醇蝴、需求分析馆蠕,數(shù)據(jù)庫(kù)表設(shè)計(jì)
需求分析:
1滓侍、登錄注冊(cè)功能绍傲;
2憾儒、首頁(yè)规哲;
3跟啤、分別展示出書(shū)籍頁(yè)面,作者頁(yè)面唉锌,出版社頁(yè)面隅肥;
4、書(shū)籍頁(yè)面功能有添加書(shū)本袄简、編輯腥放、刪除;
5绿语、作者頁(yè)面功能有添加作者秃症、編輯候址、刪除、作者詳情种柑;
6岗仑、出版社頁(yè)面功能有添加出版社、編輯聚请、刪除
數(shù)據(jù)庫(kù)表設(shè)計(jì)
一共五張表
用戶表?????User:?name? |?password?|?register_time
圖書(shū)表?????Book:?title?|?price?|?publish_time?|? publish|author
??????????(ps:publish和authors是外鍵字段)
出版社表?????Publish:?name?|?addr?|?email
作者表??????Author:?name?|?age?|?authordetail
作者詳情表?AuthorDetail:?phone?|?addr
一個(gè)出版社可以出版多本書(shū)籍荠雕,但一本書(shū)只能在一個(gè)出版社出版(一對(duì)多)
一個(gè)作者可以寫(xiě)多本書(shū),一本書(shū)也可有多個(gè)作者(多對(duì)多)
一個(gè)作者對(duì)應(yīng)一個(gè)詳情信息(一對(duì)一)
二良漱、Django環(huán)境配置
??還要在項(xiàng)目或應(yīng)用的init文件中寫(xiě)入下面代碼,告訴Django使用的是mysql數(shù)據(jù)庫(kù):
import pymysql
pymysql.install_as_MySQLdb()
三母市、圖書(shū)管理系統(tǒng)的登錄矾兜、注冊(cè)
1、路由配置(urls.py)
url(r'^$', views.login,name='login'), # 精確定位路由患久,默認(rèn)打開(kāi)就是登錄界面
url(r'^register/', views.register,name='register'),
2椅寺、前端頁(yè)面
?? 登錄界面(login.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="panel panel-primary">
<div class="panel-heading" style="background-color: lightskyblue">
<h3 class="panel-title text-center">歡迎登錄圖書(shū)管理系統(tǒng)</h3>
</div>
<div class="panel-body">
<div class="text-center">
<form action="" method="post">
<p>姓名:
<input type="text" name="name" >
</p>
<p>密碼:
<input type="text" name="password">
</p>
<input type="submit" value="登錄" class="btn btn-info" name="login" style="display: block;float: left;margin-left: 450px">
</form>
<a href="{% url 'register' %}" style="display: block;">
<button class="btn btn-danger" style="margin-left: -390px">注冊(cè)</button>
</a>
</div>
</div>
</div>
</div>
</body>
</html>
??注冊(cè)界面(register.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="panel panel-primary">
<div class="panel-heading" style="background-color: #bce8f1">
<h3 class="panel-title text-center">用戶注冊(cè)</h3>
</div>
<div class="panel-body">
<div>
<form action="" method="post">
<div class="form-group has-success">
<label class="control-label" for="inputSuccess1">用戶名</label>
<input type="text" class="form-control" id="inputSuccess1" aria-describedby="helpBlock2"
name="name">
</div>
<div class="form-group has-warning">
<label class="control-label" for="inputWarning1">密碼</label>
<input type="text" class="form-control" id="inputWarning1">
</div>
<div class="form-group has-error">
<label class="control-label" for="inputError1">確認(rèn)密碼</label>
<input type="text" class="form-control" id="inputError1" name="password">
</div>
<input type="submit" class="btn btn-success" style="display: block;float: left;margin-left: 450px">
</form>
<a href="{% url 'login' %}">
<button type="submit" class="btn btn-warning" style="margin-left: 10px">返回</button>
</a>
</div>
</div>
</div>
</div>
</body>
</html>
3、后端邏輯(views.py)
'''
登錄功能邏輯思路:
從前端獲取姓名和密碼蒋失;
判斷姓名和密碼是否為空返帕;
從數(shù)據(jù)庫(kù)的user表中查出用戶姓名和密碼;
循環(huán)列表得到用戶對(duì)象篙挽;
將用戶名和密碼與前端得到的名字和密碼進(jìn)行比對(duì)荆萤;
如果比對(duì)成功則登錄成功跳轉(zhuǎn)到home頁(yè)面;
如果比對(duì)不成功則返回一個(gè)登錄失敗頁(yè)面铣卡,顯示返回注冊(cè)
'''
def login(request):
if request.method == 'POST':
name = request.POST.get('name')
password = request.POST.get('password')
if name and password:
user_list=models.User.objects.values('name','password')
for user in user_list:
if name==user.get('name'):
if password==user.get('password'):
return redirect(reverse('home'))
else:
return HttpResponse('密碼錯(cuò)啦链韭!')
else:
return HttpResponse('請(qǐng)輸入用戶名和密碼!')
return render(request, 'login.html', locals())
'''
注冊(cè)功能邏輯:
從前端獲取姓名和密碼煮落;
判斷姓名和密碼是否為空敞峭;
從數(shù)據(jù)庫(kù)的user表中查出用戶姓名;
for循環(huán)出用戶姓名對(duì)象蝉仇;
判斷前端輸入的名字是否在用戶姓名對(duì)象里的名字中旋讹;
如果名字存在則發(fā)出提示信息;
如果不存在則進(jìn)入創(chuàng)建姓名和密碼到數(shù)據(jù)庫(kù)中轿衔;
創(chuàng)建完成跳轉(zhuǎn)到登錄界面沉迹;
'''
def register(request):
if request.method == 'POST':
name = request.POST.get('name')
password = request.POST.get('password')
if name and password:
username_list = models.User.objects.values('name')
for username in username_list:
if name in username.get('name'):
return HttpResponse('用戶已存在,請(qǐng)直接登錄害驹!')
else:
models.User.objects.create(name=name, password=password)
else:
return HttpResponse('請(qǐng)輸入用戶名和密碼鞭呕!')
return redirect(reverse('login'))
return render(request, 'register.html')
四、home主頁(yè)面搭建
1裙秋、路由配置(urls.py)
? ?這里主要是給他一個(gè)反向解析的名字琅拌,無(wú)論前端url名字怎么變化,后端都能匹配到這個(gè)路由摘刑,而且在不同的視圖函數(shù)中都能使用這個(gè)名字來(lái)定位到要解析的路由對(duì)應(yīng)的視圖函數(shù)进宝。
url(r'^home/', views.home,name='home'),
2、前端頁(yè)面(home.html)
? ?首先要導(dǎo)入bootstrap樣式枷恕,在里面找自己想要的樣式拷貝過(guò)來(lái)修改党晋。bootstrap樣式傳送門(mén):https://v3.bootcss.com/
? ?主頁(yè)面應(yīng)用的邏輯很少,主要是頁(yè)面的搭建和數(shù)據(jù)的渲染徐块。
<body>
{#導(dǎo)航條開(kāi)始#}
<nav class="navbar navbar-btn bg-info">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<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 bg-info" href="#">圖書(shū)管理系統(tǒng)</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">每日推薦 <span class="sr-only">(current)</span></a></li>
<li><a href="#">好書(shū)分享</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">圖書(shū)分類(lèi)<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">推理小說(shuō)</a></li>
<li><a href="#">經(jīng)典名著</a></li>
<li><a href="#">懸疑小說(shuō)</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">雜文</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">詩(shī)集</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">搜索</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">注銷(xiāo)</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">登錄 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
{#導(dǎo)航條結(jié)束#}
{#左邊欄開(kāi)始#}
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<!--這里要對(duì)路由進(jìn)行反向解析-->
<a href="{% url 'home' %}" class="list-group-item list-group-item-success">首頁(yè)</a>
<a href="{% url 'book_list' %}" class="list-group-item list-group-item-info">圖書(shū)列表</a>
<a href="{% url 'author_list' %}" class="list-group-item list-group-item-warning">作者列表</a>
<a href="{% url 'publish_list' %}" class="list-group-item list-group-item-danger">出版社列表</a>
</div>
<ul class="list-group">
<li class="list-group-item list-group-item-success">咸魚(yú)今天努力了沒(méi)</li>
<li class="list-group-item list-group-item-info">咸魚(yú)今天努力了嗎</li>
<li class="list-group-item list-group-item-warning">咸魚(yú)今天要努力呀</li>
<li class="list-group-item list-group-item-danger">咸魚(yú)加油</li>
</ul>
</div>
{#左邊欄結(jié)束#}
{# 右邊欄開(kāi)始#}
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading" style="background-color: lightskyblue">
<h3 class="panel-title">圖書(shū)管理系統(tǒng)</h3>
</div>
<div class="panel-body">
<!--劃分變動(dòng)區(qū)域-->
{% block content %}
<div class="jumbotron" style="background-color: #bce8f1">
<h1>咸魚(yú)今天努力了沒(méi)未玻?</h1>
<p>多讀書(shū)多看報(bào),少吃零食多睡覺(jué)</p>
</div>
{% endblock %}
</div>
</div>
</div>
{# 右邊欄開(kāi)始#}
</div>
</div>
</body>
3胡控、后端邏輯(views.py)
? ?對(duì)位填充扳剿,返回到主頁(yè)面
def home(request):
return render(request, 'home.html')
五、圖書(shū)列表頁(yè)面昼激,作者列表頁(yè)面庇绽,出版社頁(yè)面搭建
1、路由配置(urls.py)
url(r'^book_list/', views.book_list,name='book_list'),
url(r'^author_list/', views.author_list,name='author_list'),
url(r'^publish_list/', views.publish_list,name='publish_list'),
2橙困、后端邏輯(views.py)
? ?因?yàn)橐葟臄?shù)據(jù)庫(kù)中查詢(xún)出所有信息瞧掺,然后渲染到前端頁(yè)面,所以先寫(xiě)邏輯凡傅。
? ?這里查詢(xún)出來(lái)的是個(gè)queryset對(duì)象辟狈,是個(gè)列表,對(duì)象還能繼續(xù)點(diǎn)他的屬性夏跷,這里顯示名字是因?yàn)樵谀P捅碇杏胈 str_自定義print哼转,在模型層加入了如下代碼def __str__(self): return '作者對(duì)象的名字:%s'%self.name
,下面的??是查詢(xún)所有作者信息,查詢(xún)出來(lái)是作者的QuerySet 對(duì)象:
<QuerySet [<Author: 作者對(duì)象的名字:太宰治>, <Author: 作者對(duì)象的名字:東野圭吾>, <Author: 作者對(duì)象的名字:余華>, <Author: 作者對(duì)象的名字:王小波>, <Author: 作者對(duì)象的名字:wpr>, <Author: 作者對(duì)象的名字:萬(wàn)佩佩>]>
# 書(shū)籍列表
def book_list(request):
# 先查詢(xún)出所有書(shū)籍信息拓春,將內(nèi)容渲染到前端
book_list = models.Book.objects.all()
return render(request, 'book_list.html', locals())
# 作者列表
def author_list(request):
# 查詢(xún)出所有作者信息释簿,將內(nèi)容渲染到前端
author_list = models.Author.objects.all()
return render(request, 'author_list.html', locals())
# 出版社列表
def publish_list(request):
# 查詢(xún)出所有出版社信息,將內(nèi)容渲染到前端
publish_list = models.Publish.objects.all()
return render(request, 'publish_list.html', locals())
3硼莽、前端頁(yè)面(book_list.html庶溶,author_list.html,publish_list.html)
?? book_list.html
<!--繼承主頁(yè)-->
{% extends 'home.html' %}
<!--在主頁(yè)變動(dòng)區(qū)域內(nèi)寫(xiě)內(nèi)容-->
{% block content %}
<a href="{% url 'book_add' %}" class="btn bg-info">添加書(shū)籍 </a>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th style="text-align: center">id</th>
<th style="text-align: center">title</th>
<th style="text-align: center">price</th>
<th style="text-align: center">publish</th>
<th style="text-align: center">publish_time</th>
<th style="text-align: center">authors</th>
<th style="text-align: center">actions</th>
</tr>
</thead>
<tbody>
<!--從書(shū)籍列表中循環(huán)出書(shū)的對(duì)象-->
{% for book in book_list %}
<tr>
<td>{{ book.pk }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.publish.name }}</td>
<!--過(guò)濾器給時(shí)間設(shè)置格式-->
<td>{{ book.publish_time|date:'Y-m-d' }}</td>
<td>
<!--??因?yàn)闀?shū)籍中作者是作為外鍵字段懂鸵,所以從書(shū)籍表中正向查詢(xún)出所有作者偏螺,for循環(huán)出作者對(duì)象-->
{% for author_obj in book.authors.all %}
<!--??如果不是最后一個(gè)值,就在后面加匆光、隔開(kāi)套像,如果是最后一個(gè)值,forloop.last置為T(mén)rue终息,結(jié)尾就不加管道符-->
{% if forloop.last %}
{{ author_obj.name }}
{% else %}
{{ author_obj.name }}夺巩、
{% endif %}
{% endfor %}
</td>
<td style="text-align: center">
<!--??使用無(wú)名分組反向解析到編輯和刪除書(shū)籍的路由贞让,將book的id作為參數(shù)傳遞,這樣就能知道編輯和刪除的具體是哪個(gè)柳譬,綁定一一對(duì)應(yīng)的關(guān)系-->
<a href="{% url 'book_edit' book.pk %}" class="btn bg-success btn-sm" >編輯</a>
<a href="{% url 'book_delete' book.pk %}" class="btn bg-danger btn-sm">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
??:在每個(gè) {% for %}循環(huán)里有一個(gè)稱(chēng)為 forloop的模板變量喳张,這個(gè)變量有一些提示循環(huán)進(jìn)度信息的屬性。
? ???forloop.counter? 是一個(gè)表示當(dāng)前循環(huán)的執(zhí)行次數(shù)的整數(shù)計(jì)數(shù)器美澳。 這個(gè)計(jì)數(shù)器是從1開(kāi)始的销部,所以在第一次循環(huán)時(shí) forloop.counter 將會(huì)被設(shè)置為1。
? ???forloop.counter0 ?類(lèi)似于 forloop.counter 制跟,但是它是從0計(jì)數(shù)的舅桩。 第一次執(zhí)行循環(huán)時(shí)這個(gè)變量會(huì)被設(shè)置為0。
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
? ???forloop.revcounter? 是表示循環(huán)中剩余項(xiàng)的整型變量雨膨。 在循環(huán)初次執(zhí)行時(shí) forloop.revcounter 將被設(shè)置為序列中項(xiàng)的總數(shù)擂涛。 最后一次循環(huán)執(zhí)行中,這個(gè)變量將被置1哥放。
? ???forloop.revcounter0 ?類(lèi)似于 forloop.revcounter 歼指,但它以0做為結(jié)束索引。在第一次執(zhí)行循環(huán)時(shí)甥雕,該變量會(huì)被置為序列的項(xiàng)的個(gè)數(shù)減1踩身。
? ???forloop.first? 是一個(gè)布爾值,如果該迭代是第一次執(zhí)行社露,那么它被置為T(mén)rue挟阻,需要特殊處理第一個(gè)元素時(shí)很方便:
{% for object in objects %}
{% if forloop.first %}
<li class="first">
{% else %}
<li>
{% endif %}
{{ object }}
</li>
{% endfor %}
? ???forloop.last ?是一個(gè)布爾值;在最后一次執(zhí)行循環(huán)時(shí)被置為T(mén)rue峭弟。 一個(gè)常見(jiàn)的用法是在一系列的鏈接之間放置管道符(|)
{% for link in links %}
{{ link }}{% if not forloop.last %} | {% endif %}
{% endfor %}
輸出結(jié)果是:Link1 | Link2 | Link3 | Link4
另一個(gè)常見(jiàn)的用途是為列表的每個(gè)單詞的加上逗號(hào)附鸽。
<p>Favorite places:</p>
{% for p in places %}
{{ p }}{% if not forloop.last %}, {% endif %}
{% endfor %}
輸出結(jié)果是:廈門(mén),廣州瞒瘸,上海
? ???forloop.parentloop?在嵌套的循環(huán)中, forloop.parentloop引用父級(jí)循環(huán)的 forloop 對(duì)象坷备。舉個(gè)??:
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<!--循環(huán)的是父級(jí)country對(duì)象的次數(shù)-->
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
??forloop 變量只在循環(huán)內(nèi)部可用。模板解析器遇到 {% endfor %} 時(shí), forloop 隨之消失情臭,不可訪問(wèn)了省撑。
??Context和forloop變量
? ?在一個(gè) {% for %} 塊中,已存在的變量會(huì)被移除俯在,以避免 forloop 變量被覆蓋竟秫。 Django會(huì)把這個(gè)變量移動(dòng)到 forloop.parentloop 中。通常我們不用擔(dān)心這個(gè)問(wèn)題跷乐,但是一旦我們?cè)谀0逯卸x了 forloop 這個(gè)變量(當(dāng)然我們反對(duì)這樣做)肥败,在 {% for %} 塊中它會(huì)在 forloop.parentloop 被重新命名。
??author_list.html
<!--繼承主頁(yè)-->
{% extends 'home.html' %}
<!--修改分塊內(nèi)容-->
{% block content %}
<a href="{% url 'author_add' %}" class="btn bg-danger">添加作者 </a>
<table class="table table-striped table-bordered table-hover text-center">
<thead>
<tr>
<th style="text-align: center">id</th>
<th style="text-align: center">name</th>
<th style="text-align: center">age</th>
<th style="text-align: center">authordetail</th>
<th style="text-align: center">action</th>
</tr>
</thead>
<tbody>
{% for author in author_list %}
<tr>
<td>{{ author.pk }}</td>
<td>{{ author.name }}</td>
<td>{{ author.age }}</td>
<td>
<a href="{% url 'author_detail' author.pk %}" class="btn bg-success btn-sm">作者信息</a>
</td>
<td>
<a href="{% url 'author_edit' author.pk %}" class="btn bg-info btn-sm">編輯</a>
<a href="{% url 'author_delete' author.pk %}" class="btn bg-danger btn-sm">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
?? publish_list.html
<!--繼承主頁(yè)-->
{% extends 'home.html' %}
<!--編輯分塊內(nèi)容-->
{% block content %}
<a href="{% url 'publish_add' %}" class="btn bg-warning">添加出版社 </a>
<table class="table table-striped table-bordered table-hover text-center">
<thead >
<tr>
<th style="text-align: center">id</th>
<th style="text-align: center">name</th>
<th style="text-align: center">addr</th>
<th style="text-align: center">email</th>
<th style="text-align: center">action</th>
</tr>
</thead>
<tbody>
{% for publish in publish_list %}
<tr>
<td>{{ publish.pk }}</td>
<td>{{ publish.name }}</td>
<td>{{ publish.addr }}</td>
<td>{{ publish.email }}</td>
<td>
<a href="{% url 'publish_edit' publish.pk %}" class="btn bg-info btn-sm">編輯</a>
<a href="{% url 'publish_delete' publish.pk %}" class="btn bg-danger btn-sm">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
六、圖書(shū)頁(yè)面之添加書(shū)籍
1馒稍、路由配置(urls.py)
url(r'^add_book/', views.add_book,name='book_add'),
2皿哨、 前端頁(yè)面(add_book.html)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">添加書(shū)籍</h1>
<form action="" method="post">
<p>title:
<input type="text" class="form-control" name="title">
</p>
<p>price:
<input type="text" class="form-control" name="price">
</p>
<p>publish_date:
<input type="date" class="form-control" name="date">
</p>
<p>publish:
<select name="publish" id="" class="form-control">
<!--對(duì)后端查詢(xún)到的出版社列表for循環(huán),取出出版社對(duì)象-->
{% for publish in publish_list %}
<!--單選下拉框里顯示的是出版社id對(duì)應(yīng)的出版社名纽谒,value是后端接收到的publish對(duì)象的id-->
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %}
</select>
</p>
<p>authors:
<!--多選下拉框里顯示的是作者id對(duì)應(yīng)的作者名往史,value是后端接收到的author對(duì)象的id-->
<!--??這里將單選下拉框變成多選下拉框用multiple-->
<select name="authors" id="" class="form-control" multiple>
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %}
</select>
</p>
<input type="submit" class="btn bg-warning pull-right">
</form>
{% endblock %}
3、后端邏輯(views.py)
def add_book(request):
if request.method == 'POST':
title = request.POST.get('title')
price = request.POST.get('price')
# publish拿到的是publish的id
publish_id = request.POST.get('publish')
publish_date = request.POST.get('date')
authors = request.POST.getlist('authors') # [1佛舱,2,3]
# 數(shù)據(jù)庫(kù)新增數(shù)據(jù),??book表中的只有publish挨决,但是他是外鍵字段foreignkey请祖,會(huì)自動(dòng)增加_id變成publish_id,因此更新的時(shí)候這里還是要寫(xiě)publish_id
book_obj = models.Book.objects.create(title=title, price=price, publish_id=publish_id,
publish_time=publish_date)
# authors是多對(duì)多字段脖祈,去到書(shū)籍與作者的第三張表手動(dòng)創(chuàng)建關(guān)系肆捕,因?yàn)閍uthors拿出來(lái)是個(gè)列表,所以將它打散添加
book_obj.authors.add(*authors)
# 跳轉(zhuǎn)到圖書(shū)的展示頁(yè)面
return redirect(reverse('book_list'))
# 將出版社和作者數(shù)據(jù)全部傳遞給添加頁(yè)面
publish_list = models.Publish.objects.all()
author_list = models.Author.objects.all()
# get請(qǐng)求返回一個(gè)添加頁(yè)面
return render(request, 'add_book.html', locals())
七盖高、圖書(shū)頁(yè)面之編輯書(shū)籍
1慎陵、路由配置(urls.py)
url(r'^edit_book/(\d+)', views.edit_book,name='book_edit'),
2、 前端頁(yè)面(edit_book.html)
? ?編輯書(shū)籍之前喻奥,要把原信息都展示出來(lái)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">編輯書(shū)籍</h1>
<form action="" method="post">
<!--input框內(nèi)value展示出來(lái)的是原信息席纽,是從后端傳來(lái)的對(duì)象點(diǎn)屬性-->
<p>title:
<input type="text" class="form-control" name="title" value="{{ edit_obj.title }}">
</p>
<p>price:
<input type="text" class="form-control" name="price" value="{{ edit_obj.price }}">
</p>
<p>publish_date:
<input type="date" class="form-control" name="date" value="{{ edit_obj.publish_time|date:'Y-m-d' }}">
</p>
<p>publish:
<select name="publish" id="" class="form-control">
<!--?? 先f(wàn)or循環(huán)出所有出版社名;
如果要編輯對(duì)象的出版社名和上面循環(huán)出的出版社名相同撞蚕,則高亮顯示(selected表示選中)出版社的名字润梯;
ps:value是后端要接收的對(duì)應(yīng)出版社的id
-->
{% for publish in publish_list %}
{% if edit_obj.publish == publish %}
<option value="{{ publish.pk }}" selected>{{ publish.name }}</option>
{% else %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<p>authors:
<select name="authors" id="" class="form-control" multiple>
<!--?? 先f(wàn)or循環(huán)出所有作者;
如果該作者在要編輯對(duì)象的所有作者中甥厦,則高亮顯示(selected表示選中)作者的名字纺铭;
ps:value是后端要接收的對(duì)應(yīng)出版社的id
-->
{% for author in author_list %}
{% if author in edit_obj.authors.all %}
<option value="{{ author.pk }}" selected>{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<input type="submit" class="btn bg-success pull-right">
</form>
{% endblock %}
3、后端邏輯(views.py)
def edit_book(request, edit_id):
# 獲取要編輯的對(duì)象
edit_obj = models.Book.objects.filter(pk=edit_id).first()
if request.method == 'POST':
title = request.POST.get('title')
price = request.POST.get('price')
publish_date = request.POST.get('date')
publish_id = request.POST.get('publish')
# 因?yàn)橐槐緯?shū)的作者不止一個(gè)刀疙,所以要用getlist取值
authors = request.POST.getlist('authors')
# 根據(jù)要編輯的id更新數(shù)據(jù)庫(kù)中的信息
models.Book.objects.filter(pk=edit_id).update(title=title, price=price, publish_time=publish_date,
publish_id=publish_id)
# 更新作者舶赔,set里面要放可迭代對(duì)象
edit_obj.authors.set(authors)
return redirect(reverse('book_list'))
publish_list = models.Publish.objects.all()
author_list = models.Author.objects.all()
return render(request, 'edit_book.html', locals())
八、圖書(shū)頁(yè)面之刪除書(shū)籍
1谦秧、路由配置(urls.py)
url(r'^delete_book/(\d+)', views.delete_book,name='book_delete'),
2竟纳、 后端邏輯(views.py)
??因?yàn)閯h除書(shū)籍只要直接刪除就好了,沒(méi)有頁(yè)面展示油够。
def delete_book(request, delete_id):
# 根據(jù)要?jiǎng)h除對(duì)象的id來(lái)刪除對(duì)應(yīng)的書(shū)籍
models.Book.objects.filter(pk=delete_id).delete()
return redirect(reverse('book_list'))
九蚁袭、作者頁(yè)面之添加作者
1了牛、路由配置(urls.py)
url(r'^add_author/', views.add_author,name='author_add'),
2桃煎、 前端頁(yè)面(add_author.html)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">添加作者</h1>
<form action="" method="post">
<p>name:
<input type="text" class="form-control" name="name">
</p>
<p>age:
<input type="text" class="form-control" name="age">
</p>
<p>phone:
<input type="text" class="form-control" name="phone">
</p>
<span>addr:
<select name="" id="a1"></select>
<select name="addr" id="a2"></select>
</span>
<!--?? 這里使用js實(shí)現(xiàn)省市聯(lián)動(dòng)-->
<script>
let proEle=document.getElementById('a1');
let cityEle=document.getElementById('a2');
let data={"江蘇省": ["蘇州", "南京","常州","無(wú)錫"], "北京市": ["朝陽(yáng)區(qū)", "海淀區(qū)"], "上海市": ["靜安區(qū)", "閔行區(qū)"],"其他":["東京","巴黎","土星","木星"]};
// 將所有的省渲染到proEle標(biāo)簽內(nèi)部,for循環(huán)獲取所有的省
for (let pro in data){
// 創(chuàng)建option標(biāo)簽
let opEle=document.createElement('option');
// 給option標(biāo)簽設(shè)置文本值
opEle.innerText=pro;
// 將生成的option添加到proEle中
proEle.appendChild(opEle)
}
proEle.onchange=function () {
// 先清空cityEle標(biāo)簽內(nèi)所有內(nèi)容
cityEle.innerHTML='';
// 獲取用戶選擇的省弊添,根據(jù)省拿到對(duì)應(yīng)的市
let choice_pro=proEle.value;
let cityList=data[choice_pro];
// for循環(huán)創(chuàng)建option標(biāo)簽添加到cityEle標(biāo)簽內(nèi)
for(let i=0;i<cityList.length;i++){
// 創(chuàng)建option標(biāo)簽并添加文本
let cEle=document.createElement('option');
//給option標(biāo)簽設(shè)置文本值
cEle.innerText=cityList[I]
// 將生成的option添加到proEle中
cityEle.appendChild(cEle)
}
}
</script>
<input type="submit" class="btn bg-success pull-right">
</form>
{% endblock %}
3鬼悠、后端邏輯(views.py)
def add_author(request):
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
phone = request.POST.get('phone')
addr = request.POST.get('addr')
# 新增作者删性,與之一對(duì)一關(guān)系的作者詳情表也要新增信息
# 首先新增作者詳情表中的數(shù)據(jù)亏娜,賦值給作者詳情對(duì)象
authordetail_obj = models.AuthorDetail.objects.create(phone=phone, addr=addr)
# 因?yàn)槭且粚?duì)一的關(guān)系,所以在作者表中新增數(shù)據(jù)時(shí)蹬挺,作者詳情這個(gè)外鍵是和作者詳情對(duì)象的主鍵綁定的
models.Author.objects.create(name=name, age=age, authordetail_id=authordetail_obj.pk)
return redirect(reverse('author_list'))
return render(request, 'add_author.html', locals())
十维贺、作者頁(yè)面之編輯作者
1、路由配置(urls.py)
url(r'^edit_author/(\d+)', views.edit_author,name='author_edit'),
2巴帮、 前端頁(yè)面(edit_author.html)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">編輯作者信息</h1>
<form action="" method="post">
<p>name:
<input type="text" class="form-control" name="name" value="{{ edit_obj.name }}">
</p>
<p>age:
<input type="text" class="form-control" name="age" value="{{ edit_obj.age }}">
</p>
<input type="submit" class="btn bg-success pull-right">
</form>
{% endblock %}
3溯泣、后端邏輯(views.py)
def edit_author(request, edit_id):
# 先獲取要編輯的對(duì)象
edit_obj = models.Author.objects.filter(pk=edit_id).first()
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
models.Author.objects.filter(pk=edit_id).update(name=name, age=age)
return redirect(reverse('author_list'))
authordetail_list = models.AuthorDetail.objects.all()
return render(request, 'edit_author.html', locals())
十一、作者頁(yè)面之作者詳情
1榕茧、路由配置(urls.py)
url(r'^author_detail/(\d+)', views.author_detail,name='author_detail'),
2垃沦、 前端頁(yè)面(author_detail.html)
? ? 這里是跳到另外一個(gè)頁(yè)面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="panel panel-info">
<!-- Default panel contents -->
<div class="panel-heading text-center" ><h1>作者信息</h1></div>
<div class="panel-body">
<table class="table table-striped table-bordered table-hover text-center">
<thead>
<tr>
<th style="text-align: center">id</th>
{# <th style="text-align: center">name</th>#}
<th style="text-align: center">phone</th>
<th style="text-align: center">addr</th>
</tr>
</thead>
<tbody>
{% for authordetail in authordetail_list %}
<tr>
<td>{{ authordetail.pk }}</td>
{# <td>{{ author_name }}</td>#}
<td>{{ authordetail.phone }}</td>
<td>{{ authordetail.addr }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'author_list' %}" class="btn bg-success pull-right" >返回 </a>
</div>
</div>
</div>
</div>
</body>
</html>
3、后端邏輯(views.py)
def author_detail(request, detail_id):
author_obj = models.Author.objects.filter(pk=detail_id).first()
authordetail_list = models.AuthorDetail.objects.filter(pk=author_obj.authordetail_id).all()
return render(request, 'author_detail.html', locals())
十二用押、作者頁(yè)面之刪除作者
1肢簿、路由配置(urls.py)
url(r'^delete_author/(\d+)', views.delete_author,name='author_delete'),
2、后端邏輯(views.py)
def delete_author(request, delete_id):
models.Author.objects.filter(pk=delete_id).delete()
return redirect(reverse('author_list'))
十三蜻拨、出版社頁(yè)面之添加出版社
1池充、路由配置(urls.py)
url(r'^add_publish/', views.add_publish,name='publish_add'),
2、 前端頁(yè)面(edit_publish.html)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">編輯出版社</h1>
<form action="" method="post">
<p>name:
<input type="text" class="form-control" name="name" value="{{ edit_obj.name}}">
</p>
<p>addr:
<input type="text" class="form-control" name="addr" value="{{ edit_obj.addr }}">
</p>
<p>email:
<input type="text" class="form-control" name="email" value="{{ edit_obj.email }}">
</p>
<input type="submit" class="btn bg-success pull-right">
</form>
{% endblock %}
3缎讼、后端邏輯(views.py)
def add_publish(request):
if request.method == 'POST':
name = request.POST.get('name')
addr = request.POST.get('addr')
email = request.POST.get('email')
publish_obj = models.Publish.objects.create(name=name, addr=addr, email=email)
return redirect(reverse('publish_list'))
return render(request, 'add_publish.html', locals())
十四收夸、出版社頁(yè)面之編輯出版社
1、路由配置(urls.py)
url(r'^edit_publish/(\d+)', views.edit_publish,name='publish_edit'),
2血崭、 前端頁(yè)面(edit_book.html)
{% extends 'home.html' %}
{% block content %}
<h1 class="text-center">編輯書(shū)籍</h1>
<form action="" method="post">
<p>title:
<input type="text" class="form-control" name="title" value="{{ edit_obj.title }}">
</p>
<p>price:
<input type="text" class="form-control" name="price" value="{{ edit_obj.price }}">
</p>
<p>publish_date:
<input type="date" class="form-control" name="date" value="{{ edit_obj.publish_time|date:'Y-m-d' }}">
</p>
<p>publish:
<select name="publish" id="" class="form-control">
{% for publish in publish_list %}
{% if edit_obj.publish == publish %}
<option value="{{ publish.pk }}" selected>{{ publish.name }}</option>
{% else %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<p>authors:
<select name="authors" id="" class="form-control" multiple>
{% for author in author_list %}
{% if author in edit_obj.authors.all %}
<option value="{{ author.pk }}" selected>{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<input type="submit" class="btn bg-success pull-right">
</form>
{% endblock %}
3咱圆、后端邏輯(views.py)
def edit_publish(request, edit_id):
edit_obj = models.Publish.objects.filter(pk=edit_id).first()
if request.method == 'POST':
name = request.POST.get('name')
addr = request.POST.get('addr')
email = request.POST.get('email')
models.Publish.objects.filter(pk=edit_id).update(name=name, addr=addr, email=email)
return redirect(reverse('publish_list'))
return render(request, 'edit_publish.html', locals())
十五、出版社頁(yè)面之刪除出版社
1功氨、路由配置(urls.py)
url(r'^delete_publish/(\d+)', views.delete_publish,name='publish_delete'),
2序苏、后端邏輯(views.py)
def delete_publish(request, delete_id):
models.Publish.objects.filter(pk=delete_id).delete()
return redirect(reverse('publish_list'))