基礎(chǔ)-圖書(shū)管理系統(tǒng)

好好吃飯 按時(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)境配置

注冊(cè)app

注釋掉中間件舞虱,方便表單提交測(cè)試

連接數(shù)據(jù)庫(kù)

??還要在項(xiàng)目或應(yīng)用的init文件中寫(xiě)入下面代碼,告訴Django使用的是mysql數(shù)據(jù)庫(kù):

import pymysql
pymysql.install_as_MySQLdb()
配置靜態(tài)文件

三母市、圖書(shū)管理系統(tǒng)的登錄矾兜、注冊(cè)

登錄界面

注冊(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è)面搭建

主頁(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è)面搭建

圖書(shū)列表

作者列表

出版社列表

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ū)籍

添加圖書(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ū)籍

編輯圖書(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'))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捷凄,隨后出現(xiàn)的幾起案子忱详,更是在濱河造成了極大的恐慌,老刑警劉巖跺涤,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匈睁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡桶错,警方通過(guò)查閱死者的電腦和手機(jī)航唆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)院刁,“玉大人糯钙,你說(shuō)我怎么就攤上這事。” “怎么了任岸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵再榄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我享潜,道長(zhǎng)困鸥,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任剑按,我火速辦了婚禮疾就,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艺蝴。我一直安慰自己虐译,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布吴趴。 她就那樣靜靜地躺著,像睡著了一般侮攀。 火紅的嫁衣襯著肌膚如雪锣枝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天兰英,我揣著相機(jī)與錄音撇叁,去河邊找鬼。 笑死畦贸,一個(gè)胖子當(dāng)著我的面吹牛陨闹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播薄坏,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼趋厉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了胶坠?” 一聲冷哼從身側(cè)響起君账,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沈善,沒(méi)想到半個(gè)月后乡数,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闻牡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年净赴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罩润。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡玖翅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烧栋,我是刑警寧澤写妥,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站审姓,受9級(jí)特大地震影響珍特,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魔吐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一扎筒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酬姆,春花似錦嗜桌、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至相满,卻和暖如春层亿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背立美。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工匿又, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人建蹄。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓碌更,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親洞慎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痛单,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 前端相關(guān) 展示內(nèi)容:瀏覽器接收后端返回的html文本(經(jīng)過(guò)模板渲染)內(nèi)容并在頁(yè)面展示.與用戶交互信息:js將用戶產(chǎn)...
    Knight方閱讀 2,849評(píng)論 0 1
  • 一、創(chuàng)建項(xiàng)目 1.1.創(chuàng)建項(xiàng)目和app django-admin startproject mysite-logi...
    鵬ve閱讀 14,282評(píng)論 4 71
  • Django 準(zhǔn)備 “虛擬環(huán)境為什么需要虛擬環(huán)境:到目前位置劲腿,我們所有的第三方包安裝都是直接通過(guò) pip inst...
    33jubi閱讀 1,331評(píng)論 0 5
  • PythonWeb框架要點(diǎn)桦他、Django介紹、工程搭建谆棱、配置快压、靜態(tài)文件與路由 1.Python Web 框架要點(diǎn) ...
    Cestine閱讀 1,510評(píng)論 0 6
  • Django是一個(gè)用 Python 編寫(xiě)的 Web 框架。Web 框架是一種軟件垃瞧,基于web框架可以開(kāi)發(fā)動(dòng)態(tài)網(wǎng)站蔫劣,...
    guanalex閱讀 7,202評(píng)論 0 5