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
>
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參數
<
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 有關書籍的函數邏輯
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
>
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參數
<
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
>
12.323 有關作者的函數邏輯
#
作者列表函數
def
author_list(request):
authors
= models.Author.objects.all()
#
從數據庫中查詢所有的作者數據,在頁面上展示出來
#
author_obj = models.Author.objects.get(id=1)
#
print(author_obj.books.all()) 表示id=1的作者寫的所有書的對象
return
render(request,
"
author_list.html
"
, {
"
author_list
"
: authors})
#
添加作者函數
def
add_author(request):
if
request.method ==
"
POST
"
:
new_author_name
= request.POST.get(
"
author_name
"
)
#
拿到新的作者姓名
models.Author.objects.create(name=new_author_name)
#
去數據庫中創建一個新的作者記錄
return
redirect(
"
/author_list/
"
)
#
創建好作者之后,讓用戶跳轉到作者列表頁面
#
返回一個頁面,讓用戶填寫新的作者信息
return
render(request,
"
add_author.html
"
)
#
刪除作者函數
def
delete_author(request):
delete_author_id
= request.GET.get(
"
id
"
)
#
從URL里面取到要刪除的作者的ID
models.Author.objects.get(id=delete_author_id).delete()
#
去數據庫中找到該作者并刪除
return
redirect(
"
/author_list/
"
)
#
刪除成功后 跳轉回作者列表頁面
#
編輯作者函數
def
edit_author(request):
if
request.method ==
"
POST
"
:
#
如果發送的是POST請求,應該拿到用戶提交的數據
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
"
)
#
如果提交過來的數據是多個值(多選的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更換作者對應的書籍,并提交數據庫
return
redirect(
"
/author_list/
"
)
#
修改完成之后,跳轉到作者列表頁面
#
返回一個頁面,讓用戶編輯
edit_author_id = request.GET.get(
"
id
"
)
#
從URL里面取到要編輯作者的id參數
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
>
#在這一列展示這個作者關聯的所有的書籍
{% 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=""默認轉到當前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
>
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

