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

来源:https://www.cnblogs.com/mylu/archive/2019/08/26/11415113.html
-Advertisement-
Play Games

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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 單例定義: 一個類只有一個實例,並提供一個全局訪問點。 巧妙利用了編程語言的一些語法規則:構造函數private, 然後提供一個public的方法返回類的一個實例;又方法和返回的類的實例都是static類型,所以只能被類所擁有,而不能被實例化類的對象擁有。這樣一個類就只能有一個實例了。 2. 加”s ...
  • 函數的定義與調用 在Scala中定義函數時,需要定義函數的函數名、參數、函數體。 我們的第一個函數如下所示: def sayHello(name: String, age: Int) = { if (age > 18) { printf("hi %s, you are a big boy\n", n ...
  • JavaFX的對話框主要分為提示對話框和文件對話框兩類,其中提示對話框又分作消息對話框、警告對話框、錯誤對話框、確認對話框四種。這四種對話框都使用Alert控制項表達,並通過對話框類型加以區分,例如AlertType.INFORMATION表示消息對話框,AlertType.WARNIN表示警告對話框 ...
  • 攔截器配置類使用繼承寫法導致jackson的全局配置失效,採用配置類實現WebMvcConfigurer介面解決問題 ...
  • Scala解釋器的使用 ·REPL:Read(取值)-> Evaluation(求值)-> Print(列印)-> Loop(迴圈)。scala解釋器也被稱為REPL,會快速編譯scala代碼為位元組碼,然後交給JVM來執行。 ·計算表達式:在scala>命令行內,鍵入scala代碼,解釋器會直接返回 ...
  • Django之視圖,內容包括 視圖,HttpReqeust對象,ajax請求。其中,視圖 包括 視圖函數的使用,url匹配的過程,錯誤視圖處理,捕捉url參數,普通登錄案例;HttpReqeust對象 包括 屬性,QueryDict對象;ajax請求 包括 python和ajax結合使用,ajax同... ...
  • 從Java1.4開始,為了替代Java IO和網路相關的API,提高程式的運行速度,Java提供了新的IO操作非阻塞的API即Java NIO。NIO中有三大核心組件:Buffer(緩衝區),Channel(通道),Selector(選擇器)。NIO基於Channel(通道)和Buffer(緩衝區) ...
  • 近日,在閱讀《Fluent Python》的第2.9.2節時,有一個關於記憶體視圖的例子,當時看的一知半解,後來查了一些資料,現在總結一下,以備後續查詢; 示例覆述 添加了一些額外的代碼,便於更好理解 我的理解和疑惑 是一個 類型的數組; 是使用上述數組創建的一個 "memoryview" ,即 記憶體 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...