python 之 Django框架(APP和ORM的使用)


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()    # 從數據庫中查詢所有的作者數據,在頁面上展示出來
    # 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>
View Code

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>
View Code

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>
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM