12.3 APP 12.31 創建APP 一個Django項目可以分為很多個APP,用來隔離不同功能模塊的代碼 用命令行創建一個APP: 創建好APP,記得告訴Django,app的名字,在settings.py中添加: 12.32 Django中的ORM Django項目使用MySQL資料庫 1. ...
12.3 APP
12.31 創建APP
一個Django項目可以分為很多個APP,用來隔離不同功能模塊的代碼
用命令行創建一個APP:
python3 manage.py startapp app01
創建好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資料庫
1.在Django項目的settings.py文件中,配置資料庫連接信息:告訴Django連接哪個資料庫
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "db6", # 需要自己手動先創建資料庫 "USER": "root", "PASSWORD": "", "HOST": "127.0.0.1", "PORT": 3306 } }
2.Django預設使用的是 MySQLdb模塊 連接資料庫,但 MySQLdb在python3中不支持,所以:
在與Django項目同名的文件夾的__init__
.py文件中寫如下代碼,告訴Django使用pymysql模塊連接MySQL資料庫代替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") # 外鍵關聯Publisher這張表 # 作者 class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=16) books = models.ManyToManyField(to="Book") # ORM創建多對多欄位,會自動在資料庫中創建第三張表 id Author_id、Book_id
用命令行執行創建表的操作:
1. python3 manage.py makemigrations --> 將models.py的修改登記到小本本上
2. python3 manage.py migrate --> 將修改翻譯成SQL語句,去資料庫執行
4.在app/views.py文件中寫urls.py中 /publisher_list/ 的對應函數publisher_list;/add_publisher/的對應函數add_publisher
urls.py中的對應關係:
from django.conf.urls import url from django.contrib import admin from app01 import views # 對應關係 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) # 以上對應關係都找不到,就匹配出版社頁面 ]
app/views.py:
12.321 有關出版社的函數邏輯
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 顯示出版社列表 def publisher_list(request): ret = models.Publisher.objects.all() # 從資料庫中取出所有的數據對象列表 #print(ret) return render(request, "publisher_list.html", {"publisher_list": ret}) #添加出版社函數 def add_publisher(request): # 根據請求方法的不同,要做不同的事情,add_publisher.html使用POST方法 if request.method == "POST":#request.method獲取的是請求的方法(GET、POST...必須是大寫) #request.POST(字典)獲取POST提交過來的全部數據 new_publisher_name = request.POST.get("publisher_name") models.Publisher.objects.create(name=new_publisher_name)#創建對象並封裝屬性(插入一行數據) #或者自己用類實例化一個對象:obj=models.Publisher(name=new_publisher_name) obj.save() #讓用戶跳轉到publisher_list.html,顯示新增數據後的publisher_list.html頁面 return redirect("/publisher_list/") return render(request, "add_publisher.html") # 刪除出版社函數 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)#根據id值得到對象 obj.delete() #將數據刪除 return redirect("/publisher_list/") #讓用戶重新訪問publisher_list.html更新頁面 # 編輯出版社的函數 def edit_publisher(request): #edit_id = request.GET.get("id")如果用戶提交使用URL拼接id,那麼從URL裡面取id參數request.GET.get("id") if request.method == "POST": #如果是post請求,表示用戶已經編輯好了,向服務端提交修改後的新數據 edit_id = request.POST.get("edit_id") # 拿到已經修改的出版社id new_name = request.POST.get("name") # 拿到修改之後的出版社的名字 edit_obj = models.Publisher.objects.get(id=edit_id)#通過id找到數據行對象 edit_obj.name = new_name edit_obj.save() #保存修改,提交資料庫 return redirect("/publisher_list/") # 修改成功,讓用戶跳轉到出版社列表頁面,更新頁面 #如果不是post請求,則返回edit_publisher.html頁面給用戶修改出版社 edit_id = request.GET.get("id") #先獲取編輯的出版社的ID值 obj = models.Publisher.objects.get(id=edit_id) #根據id值去資料庫找對應的行數據對象 return render(request, "edit_publisher.html", {"publisher": obj})#將數據想要編輯的出版社顯示出來,等待用戶編輯
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 }計數表格中的數據條數,從而刪除後更新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>View Code
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>View Code
templates/edit_publisher.html:
#如果#action="/edit_publisher/?id={{ publisher.id }}"那麼就從URL中用request.GET.get()取id參數 <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>View Code
12.322 有關書籍的函數邏輯
from django.shortcuts import HttpResponse, render, redirect from app01 import models # 書籍列表函數 def book_list(request): ret = models.Book.objects.all() #去資料庫查詢所有的書籍對象 return render(request, "book_list.html", {"book_list": ret})#將數據填充到頁面上,發送給客戶端 # 添加書籍函數 def add_book(request): if request.method == "POST": #如果是POST請求表示用戶新添加了一本書籍和關聯的出版社 book_name = request.POST.get("book_name") # 添加新書籍的名稱 publisher_id = request.POST.get("publisher_id") # 添加新書籍關聯的出版社id值 models.Book.objects.create(title=book_name, publisher_id=publisher_id) #publisher_obj = models.Publisher.objects.get(id=publisher_id)#根據id值先找到關聯的出版社對象 #models.Book.objects.create(title=book_name, publisher=publisher_obj) return redirect("/book_list/") # 創建成功,讓用戶跳轉到書籍列表頁面,刷新數據 # 取到所有的出版社數據,在頁面上渲染成select標簽,供用戶選擇 ret = models.Publisher.objects.all() return render(request, "add_book.html", {"publisher_list": ret}) # 刪除書籍的函數 def delete_book(request): delete_book_id = request.GET.get("id") # 從URL裡面取到要刪除的書籍的ID models.Book.objects.get(id=delete_book_id).delete()# 去資料庫中刪除 return redirect("/book_list/") # 刪除成功,跳轉到書籍列表頁面,刷新數據 # 編輯書籍的函數 def edit_book(request): if request.method == "POST": # 如果是POST請求 表名是用戶修改好了數據,向後端提交了 new_book_title = request.POST.get("book_title") # 取用戶提交過來的數據 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)# 根據id取出要編輯的書籍對象 book_obj.title = new_book_title book_obj.publisher_id = new_publisher_id book_obj.save() # 將修改保存到資料庫 return redirect("/book_list/") # 修改完之後讓用戶跳轉回書籍列表頁面 # 返回一個讓用戶編輯數據的頁面 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() # 去資料庫查詢目前所有的出版社數據 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)關聯的出版社的行數據對象 <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>View Code
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>View Code
templates/edit_book.html:
#action=""此處使用預設URL,即繼承之前的/edit_book/?id={{ book.id }} #或者#action="/edit_publisher/?id={{ publisher.id }}"那麼就從URL中用request.GET.get()取id參數 <form class="form-horizontal" action="" method="post"> #隱藏要編輯的書,發送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"> # 如果當前迴圈到的出版社和書關聯的出版社相等,則添加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>View Code
12.323 有關作者的函數邏輯
# 作者列表函數 def author_list(request): authors = models.Author.objects.all() # 從資料庫中查詢所有的作者數據,在頁面上展示出來 #