12.3 APP
12.31 創(chuàng)建APP
一個Django項目可以分為很多個APP,用來隔離不同功能模塊的代碼
用命令行創(chuàng)建一個APP:
python3 manage.py startapp app01
創(chuàng)建好APP,記得告訴Django,app的名字,在settings.py中添加:
INSTALLED_APPS = [ ' django.contrib.admin ' , ' django.contrib.auth ' , ' django.contrib.contenttypes ' , ' django.contrib.sessions ' , ' django.contrib.messages ' , ' django.contrib.staticfiles ' , ' app01 ' , # 或者'app01.apps.App01Config', ]
12.32 Django中的ORM
Django項目使用MySQL數(shù)據(jù)庫
1.在Django項目的 settings.py 文件中,配置數(shù)據(jù)庫連接信息: 告訴Django連接哪個數(shù)據(jù)庫
DATABASES = { " default " : { " ENGINE " : " django.db.backends.mysql " , " NAME " : " db6 " , # 需要自己手動先創(chuàng)建數(shù)據(jù)庫 " USER " : " root " , " PASSWORD " : "" , " HOST " : " 127.0.0.1 " , " PORT " : 3306 } }
2.Django默認使用的是 MySQLdb模塊 連接數(shù)據(jù)庫,但 MySQLdb在python3中不支持,所以:
在與
Django項目同名的文件夾的
__init__
.py
文件中寫如下代碼,
告訴Django使用pymysql模塊連接MySQL數(shù)據(jù)庫代替MySQLdb:
import pymysql pymysql.install_as_MySQLdb()
3.在 app/models.py 文件中定義類,一定要繼承 models.Model
from django.db import models ? class User(models.Model): id = models.AutoField(primary_key=True) # 自增主鍵 name = models.CharField(max_length=16) # varchar(16) pwd = models.CharField(max_length=128) # varchar(128) ? # 出版社 class Publisher(models.Model): id = models.AutoField(primary_key=True) # 自增主鍵 name = models.CharField(max_length=16) # varchar(16) # 出版社名稱 ? # def __str__(self): #定義__str__是在打印表的對象時可以看到每一行的字段 # return (self.id,self.name) ? # 書籍 class Book(models.Model): id = models.AutoField(primary_key=True) # 自增的主鍵 title = models.CharField(max_length=32) # 書籍名稱 varchar(32) publisher = models.ForeignKey(to= " Publisher " ) # 外鍵關(guān)聯(lián)Publisher這張表 ? # 作者 class Author(models.Model): id = models.AutoField(primary_key= True) name = models.CharField(max_length=16 ) books = models.ManyToManyField(to= " Book " ) # ORM創(chuàng)建多對多字段,會自動在數(shù)據(jù)庫中創(chuàng)建第三張表 id Author_id、Book_id
用命令行執(zhí)行創(chuàng)建表的操作:
1. python3 manage.py makemigrations -->
將models.py的修改登記到小本本上
2. python3 manage.py migrate --> 將修改翻譯成SQL語句,去數(shù)據(jù)庫執(zhí)行
4.在app/views.py文件中寫urls.py中 /publisher_list/ 的對應函數(shù) publisher_list ; /add_publisher/ 的對應函數(shù) add_publisher
urls.py中的對應關(guān)系:
from django.conf.urls import url from django.contrib import admin from app01 import views ? # 對應關(guān)系 urlpatterns = [ url(r ' ^admin/ ' , admin.site.urls), url(r ' ^login/ ' , views.login), url(r ' ^publisher_list/ ' , views.publisher_list), # 展示出版社列表 url(r ' ^add_publisher/ ' , views.add_publisher), # 添加出版社 url(r ' ^delete_publisher/ ' , views.delete_publisher), # 刪除出版社 url(r ' ^edit_publisher/ ' , views.edit_publisher), # 編輯出版社 url(r ' ^book_list/ ' , views.book_list), # 書籍列表 url(r ' ^add_book/ ' , views.add_book), # 添加書籍 url(r ' ^delete_book/ ' , views.delete_book # 刪除書籍 url(r ' ^edit_book/ ' , views.edit_book), # 編輯書籍 url(r ' ^author_list/ ' , views.author_list), # 作者列表 url(r ' ^add_author/ ' , views.add_author), # 添加作者 url(r ' ^delete_author/ ' , views.delete_author), # 刪除作者 url(r ' ^edit_author/ ' , views.edit_author), # 編輯作者 url(r ' ^$ ' , views.publisher_list) # 以上對應關(guān)系都找不到,就匹配出版社頁面 ]
app/views.py:
12.321 有關(guān)出版社的函數(shù)邏輯
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 顯示出版社列表 def publisher_list(request): ret = models.Publisher.objects.all() # 從數(shù)據(jù)庫中取出所有的數(shù)據(jù)對象列表 # print(ret) return render(request, " publisher_list.html " , { " publisher_list " : ret}) ? # 添加出版社函數(shù) def add_publisher(request): # 根據(jù)請求方法的不同,要做不同的事情,add_publisher.html使用POST方法 if request.method == " POST " : # request.method獲取的是請求的方法(GET、POST...必須是大寫) # request.POST(字典)獲取POST提交過來的全部數(shù)據(jù) new_publisher_name = request.POST.get( " publisher_name " ) models.Publisher.objects.create(name =new_publisher_name) # 創(chuàng)建對象并封裝屬性(插入一行數(shù)據(jù)) # 或者自己用類實例化一個對象:obj=models.Publisher(name=new_publisher_name) obj.save() # 讓用戶跳轉(zhuǎn)到publisher_list.html,顯示新增數(shù)據(jù)后的publisher_list.html頁面 return redirect( " /publisher_list/ " ) return render(request, " add_publisher.html " ) ? # 刪除出版社函數(shù) def delete_publisher(request): # print(request.method) # print(request.GET) delete_id = request.GET.get( " id " ) # 拿到用戶要刪除的出版社的id值 # print(delete_id) obj = models.Publisher.objects.get(id=delete_id) # 根據(jù)id值得到對象 obj.delete() # 將數(shù)據(jù)刪除 return redirect( " /publisher_list/ " ) # 讓用戶重新訪問publisher_list.html更新頁面 ? # 編輯出版社的函數(shù) def edit_publisher(request): # edit_id = request.GET.get("id")如果用戶提交使用URL拼接id,那么從URL里面取id參數(shù)request.GET.get("id") if request.method == " POST " : # 如果是post請求,表示用戶已經(jīng)編輯好了,向服務端提交修改后的新數(shù)據(jù) edit_id = request.POST.get( " edit_id " ) # 拿到已經(jīng)修改的出版社id new_name = request.POST.get( " name " ) # 拿到修改之后的出版社的名字 edit_obj = models.Publisher.objects.get(id=edit_id) # 通過id找到數(shù)據(jù)行對象 edit_obj.name = new_name edit_obj.save() # 保存修改,提交數(shù)據(jù)庫 return redirect( " /publisher_list/ " ) # 修改成功,讓用戶跳轉(zhuǎn)到出版社列表頁面,更新頁面 ? # 如果不是post請求,則返回edit_publisher.html頁面給用戶修改出版社 edit_id = request.GET.get( " id " ) # 先獲取編輯的出版社的ID值 obj = models.Publisher.objects.get(id=edit_id) # 根據(jù)id值去數(shù)據(jù)庫找對應的行數(shù)據(jù)對象 return render(request, " edit_publisher.html " , { " publisher " : obj}) # 將數(shù)據(jù)想要編輯的出版社顯示出來,等待用戶編輯
templates/publisher_list.html:

< body > < table border ="1" > < thead > < tr > < th > # th > < th > 出版社名稱 th > tr > thead > < tbody > {% for publisher in publisher_list %} < tr > < td > {{ publisher.id }} td > #{{ forloop.counter }計數(shù)表格中的數(shù)據(jù)條數(shù),從而刪除后更新id < td > {{ publisher.name }} td > < td class ="text-center" > < a class ="btn btn-info btn-sm" href ="/edit_publisher/?id={{ publisher.id }}" > < i class ="fa fa-pencil fa-fw" aria-hidden ="true" > i > 編輯 a > < a class ="btn btn-danger btn-sm" href ="/delete_publisher/?id={{ publisher.id }}" > < i class ="fa fa-trash-o fa-fw" aria-hidden ="true" > i > 刪除 a > td > tr > {% endfor %} tbody > table > body >
templates/add_publisher.html:

< body > < h1 > 添加新的出版社 h1 > < form action ="/add_publisher/" method ="post" > < input type ="text" name ="publisher_name" > < input type ="submit" value ="提交" > form > body >
templates/edit_publisher.html:

#如果#action="/edit_publisher/?id={{ publisher.id }}"那么就從URL中用request.GET.get()取id參數(shù) < form class ="form-horizontal" action ="/edit_publisher/" method ="post" > < input type ="text" name ="edit_id" value ="{{ publisher.id }}" class ="hide" > #將獲取id的input框隱藏 < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 出版社名稱 label > < div class ="col-sm-9" > < input type ="text" class ="form-control" id ="inputEmail3" name ="name" placeholder ="出版社名稱" value ="{{ publisher.name }}" > #提交出版社名稱 div > div > ? < div class ="form-group" > < div class ="col-sm-offset-3 col-sm-9" > < button type ="submit" class ="btn btn-default" > 提交 button > div > div > form >
12.322 有關(guān)書籍的函數(shù)邏輯
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 書籍列表函數(shù) def book_list(request): ret = models.Book.objects.all() # 去數(shù)據(jù)庫查詢所有的書籍對象 return render(request, " book_list.html " , { " book_list " : ret}) # 將數(shù)據(jù)填充到頁面上,發(fā)送給客戶端 ? # 添加書籍函數(shù) def add_book(request): if request.method == " POST " : # 如果是POST請求表示用戶新添加了一本書籍和關(guān)聯(lián)的出版社 book_name = request.POST.get( " book_name " ) # 添加新書籍的名稱 publisher_id = request.POST.get( " publisher_id " ) # 添加新書籍關(guān)聯(lián)的出版社id值 models.Book.objects.create(title=book_name, publisher_id= publisher_id) # publisher_obj = models.Publisher.objects.get(id=publisher_id)#根據(jù)id值先找到關(guān)聯(lián)的出版社對象 # models.Book.objects.create(title=book_name, publisher=publisher_obj) return redirect( " /book_list/ " ) # 創(chuàng)建成功,讓用戶跳轉(zhuǎn)到書籍列表頁面,刷新數(shù)據(jù) ? # 取到所有的出版社數(shù)據(jù),在頁面上渲染成select標簽,供用戶選擇 ret = models.Publisher.objects.all() return render(request, " add_book.html " , { " publisher_list " : ret}) ? # 刪除書籍的函數(shù) def delete_book(request): delete_book_id = request.GET.get( " id " ) # 從URL里面取到要刪除的書籍的ID models.Book.objects.get(id=delete_book_id).delete() # 去數(shù)據(jù)庫中刪除 return redirect( " /book_list/ " ) # 刪除成功,跳轉(zhuǎn)到書籍列表頁面,刷新數(shù)據(jù) ? # 編輯書籍的函數(shù) def edit_book(request): if request.method == " POST " : # 如果是POST請求 表名是用戶修改好了數(shù)據(jù),向后端提交了 new_book_title = request.POST.get( " book_title " ) # 取用戶提交過來的數(shù)據(jù) new_publisher_id = request.POST.get( " publisher_id " ) book_id = request.GET.get( " id " ) # 獲取URL中的當前編輯圖書的id book_obj = models.Book.objects.get(id=book_id) # 根據(jù)id取出要編輯的書籍對象 book_obj.title = new_book_title book_obj.publisher_id = new_publisher_id book_obj.save() # 將修改保存到數(shù)據(jù)庫 return redirect( " /book_list/ " ) # 修改完之后讓用戶跳轉(zhuǎn)回書籍列表頁面 ? # 返回一個讓用戶編輯數(shù)據(jù)的頁面 edit_book_id = request.GET.get( " id " ) # 取編輯的書籍的id值 edit_book_obj = models.Book.objects.get(id=edit_book_id) # 取到要編輯的書籍對象 publisher_list = models.Publisher.objects.all() # 去數(shù)據(jù)庫查詢目前所有的出版社數(shù)據(jù) return render(request, " edit_book.html " ,{ " book " : edit_book_obj, " publisher_list " :publisher_list})
templates/book_list.html:

< table class ="table table-striped table-bordered" > < thead > < tr > < th > 序號 th > < th > 書籍名稱 th > < th > 出版社名稱 th > < th > 操作 th > tr > thead > < tbody > {% for book in book_list %} < tr > < td > {{ forloop.counter }} td > < td > {{ book.title }} td > < td > {{ book.publisher.name}} td > # book.publisher拿到的是外鍵(id)關(guān)聯(lián)的出版社的行數(shù)據(jù)對象 < td class ="text-center" > < a class ="btn btn-info btn-sm" href ="/edit_book/?id={{ book.id }}" > < i class ="fa fa-pencil fa-fw" aria-hidden ="true" > i > 編輯 a > < a class ="btn btn-danger btn-sm" href ="/delete_book/?id={{ book.id }}" > < i class ="fa fa-trash-o fa-fw" aria-hidden ="true" > i > 刪除 a > td > tr > {% endfor %} tbody > table >
templates/add_book.html:

< form class ="form-horizontal" action ="/add_book/" method ="post" > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 書籍名稱 label > < div class ="col-sm-9" >< input type ="text" class ="form-control" id ="inputEmail3" name ="book_name" placeholder ="書籍名稱" > div > div > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 出版社名稱 label > < div class ="col-sm-9" > < select class ="form-control" name ="publisher_id" > {% for publisher in publisher_list %} < option value ="{{ publisher.id }}" > {{ publisher.name }} option > {% endfor %} select > div > div > < div class ="form-group" > < div class ="col-sm-offset-3 col-sm-9" >< button type ="submit" class ="btn btn-default" > 提交 button > div > div > form >
templates/edit_book.html:

#action=""此處使用默認URL,即繼承之前的/edit_book/?id={{ book.id }} #或者#action="/edit_publisher/?id={{ publisher.id }}"那么就從URL中用request.GET.get()取id參數(shù) < form class ="form-horizontal" action ="" method ="post" > #隱藏要編輯的書,發(fā)送id到后端,為了在后端找到要修改的圖書,方便修改 # < input type ="text" value ="{{ book.id }}" name ="book_id" class ="hide" > #預先在輸入框和下拉框顯示要修改的圖書名和出版社名 < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 書籍名稱 label > < div class ="col-sm-9" > < input type ="text" class ="form-control" id ="inputEmail3" name ="book_title" value ="{{ book.title }}" placeholder ="書籍名稱" > div > div > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 出版社名稱 label > < div class ="col-sm-9" > < select class ="form-control" name ="publisher_id" > # 如果當前循環(huán)到的出版社和書關(guān)聯(lián)的出版社相等,則添加selected,表示預先選中的 {% for publisher in publisher_list %} {% if publisher == book.publisher %} < option value ="{{ publisher.id }}" selected > {{ publisher.name }} option > {% else %} < option value ="{{ publisher.id }}" > {{ publisher.name }} option > {% endif %} {% endfor %} select > div > div > ? < div class ="form-group" > < div class ="col-sm-offset-3 col-sm-9" > < button type ="submit" class ="btn btn-default" > 提交 button > div > div > form >
12.323 有關(guān)作者的函數(shù)邏輯
# 作者列表函數(shù) def author_list(request): authors = models.Author.objects.all() # 從數(shù)據(jù)庫中查詢所有的作者數(shù)據(jù),在頁面上展示出來 # author_obj = models.Author.objects.get(id=1) # print(author_obj.books.all()) 表示id=1的作者寫的所有書的對象 return render(request, " author_list.html " , { " author_list " : authors}) # 添加作者函數(shù) def add_author(request): if request.method == " POST " : new_author_name = request.POST.get( " author_name " ) # 拿到新的作者姓名 models.Author.objects.create(name=new_author_name) # 去數(shù)據(jù)庫中創(chuàng)建一個新的作者記錄 return redirect( " /author_list/ " ) # 創(chuàng)建好作者之后,讓用戶跳轉(zhuǎn)到作者列表頁面 # 返回一個頁面,讓用戶填寫新的作者信息 return render(request, " add_author.html " ) # 刪除作者函數(shù) def delete_author(request): delete_author_id = request.GET.get( " id " ) # 從URL里面取到要刪除的作者的ID models.Author.objects.get(id=delete_author_id).delete() # 去數(shù)據(jù)庫中找到該作者并刪除 return redirect( " /author_list/ " ) # 刪除成功后 跳轉(zhuǎn)回作者列表頁面 # 編輯作者函數(shù) def edit_author(request): if request.method == " POST " : # 如果發(fā)送的是POST請求,應該拿到用戶提交的數(shù)據(jù) edit_author_id = request.POST.get( " author_id " ) # 編輯的作者id # 取新名字和新的書籍id new_author_name = request.POST.get( " author_name " ) new_book_ids = request.POST.getlist( " book_ids " ) # 如果提交過來的數(shù)據(jù)是多個值(多選的select/多選的checkbox)則使用getlist取列表 # print(request.POST) # print(edit_author_id, new_author_name, new_book_ids) # 去編輯作者以及對應的書籍 edit_author_obj = models.Author.objects.get(id=edit_author_id) # 拿到編輯的作者對象 edit_author_obj.name = new_author_name # 修改作者姓名 edit_author_obj.save() # 修改作者寫的書籍 edit_author_obj.books.set(new_book_ids) # 通過新書id更換作者對應的書籍,并提交數(shù)據(jù)庫 return redirect( " /author_list/ " ) # 修改完成之后,跳轉(zhuǎn)到作者列表頁面 # 返回一個頁面,讓用戶編輯 edit_author_id = request.GET.get( " id " ) # 從URL里面取到要編輯作者的id參數(shù) edit_author_obj = models.Author.objects.get(id=edit_author_id) # 取到要編輯的作者對象 book_list = models.Book.objects.all() # 獲取所有的書籍對象信息 return render(request, " edit_author.html " ,{ " author " : edit_author_obj,
templates/author_list.html:

< div class ="col-md-3 col-sm-6 pull-right add-btn" > < button data-target ="#myModal" data-toggle ="modal" class ="btn btn-success pull-right" > 新增 button > < a href ="/add_author/" class ="btn btn-info pull-right" > 新頁面添加 a > div > ? < table class ="table table-striped table-bordered" > < thead > < tr > < th > 序號 th > < th > 作者姓名 th > < th > 著作 th > < th > 操作 th > tr > thead > < tbody > {% for author in author_list %}#{"author_list": authors} < tr > < td > {{ forloop.counter }} td > < td > {{ author.name }} td > < td > #在這一列展示這個作者關(guān)聯(lián)的所有的書籍 {% for book in author.books.all %}#書籍對象的列表 {% if forloop.last %} 《{{ book.title }}》 {% else %} 《{{ book.title }}》, {% endif %} {% empty %} 暫無著作 {% endfor %} td > < td class ="text-center" > < a class ="btn btn-info btn-sm" href ="/edit_author/?id={{ author.id }}" > < i class ="fa fa-pencil fa-fw" aria-hidden ="true" > i > 編輯 a > < a class ="btn btn-danger btn-sm" href ="/delete_author/?id={{ author.id }}" > < i class ="fa fa-trash-o fa-fw" aria-hidden ="true" > i > 刪除 a > td > tr > {% endfor %} tbody > table >
templates/add_author.html:

< form class ="form-horizontal" action ="/add_author/" method ="post" > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 作者姓名 label > < div class ="col-sm-9" > < input type ="text" class ="form-control" id ="inputEmail3" name ="author_name" placeholder ="作者姓名" > div > div > ? < div class ="form-group" > < div class ="col-sm-offset-3 col-sm-9" > < button type ="submit" class ="btn btn-default" > 提交 button > div > div > form >
templates/edit_author.html:

< form class ="form-horizontal" action ="" method ="post" > #action=""默認轉(zhuǎn)到當前URL < input type ="text" value ="{{ author.id }}" name ="author_id" class ="hide" > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 作者姓名 label > < div class ="col-sm-9" > < input type ="text" class ="form-control" id ="inputEmail3" name ="author_name" value ="{{ author.name }}" placeholder ="作者姓名" > div > div > < div class ="form-group" > < label for ="inputEmail3" class ="col-sm-3 control-label" > 著作 label > < div class ="col-sm-9" > < select class ="form-control" name ="book_ids" multiple > {% for book in book_list %} #book_list 所有的書籍對象 #author:要編輯的作者,author.books.all:要編輯的作者的所有書籍對象 {% if book in author.books.all %} # 如果當前這本書在作者寫的書里面 < option value ="{{ book.id }}" selected > {{ book.title }} option > {% else %} < option value ="{{ book.id }}" > {{ book.title }} option > {% endif %} {% endfor %} select > div > div > ? < div class ="form-group" > < div class ="col-sm-offset-3 col-sm-9" > < button type ="submit" class ="btn btn-default" > 提交 button > div > div > form >
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
