久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Django筆記5---ORM

 印度阿三17 2019-12-02

在前后端的交互中,除了簡單的業(yè)務(wù)邏輯以外,現(xiàn)代web應(yīng)用的背后都是數(shù)據(jù)庫在支撐.Django的數(shù)據(jù)庫操作采用ORM模型,與之前學(xué)過的sqlalchemy異曲同工.

ORM的核心就是以類和對象來操作數(shù)據(jù)庫,而不用管數(shù)據(jù)庫底層是什么類型的數(shù)據(jù)庫,只要選擇好驅(qū)動就可以進行操作.

ORM模型的核心觀點:

  • 類=數(shù)據(jù)庫的表
  • 對象=數(shù)據(jù)庫的一行數(shù)據(jù)
  • 對象的屬性=字段內(nèi)容

ORM可以對表和其中的數(shù)據(jù)進行修改,但無法操作數(shù)據(jù)庫.

使用ORM的準(zhǔn)備工作

由于之前了解了一些關(guān)于ORM的內(nèi)容,所以直接來進行操作.在MySql里建立了一個名字叫做mydata的數(shù)據(jù)庫,不用創(chuàng)建任何表格,之后打算把這個數(shù)據(jù)庫交個Django處理,所以需要在settings.py里配置數(shù)據(jù)庫相關(guān)內(nèi)容.

DATABASES = {
    'default': {
        # 使用的數(shù)據(jù)庫類型(引擎)
        'ENGINE': 'django.db.backends.mysql',
        # 連接數(shù)據(jù)庫的地址
        "HOST": "127.0.0.1",
        # 端口
        "PORT": 3306,
        # 數(shù)據(jù)庫名稱
        "NAME": "mydata",
        # 用戶
        "USER": 'root',
        # 密碼
        "PASSWORD": "conyli.cc"
    }
}

將數(shù)據(jù)庫的地址,端口,用戶和密碼以及數(shù)據(jù)庫名稱寫在默認配置中.然后需要選擇具體操作數(shù)據(jù)庫的模塊.在項目的__init__.py中,加上如下兩句話:

import pymysql
pymysql.install_as_MySQLdb()

這樣就會用pymysql代替默認的MySQLdb模塊讓Django去連接.
之后就是編寫具體代碼了,注意,ORM模塊的代碼,只能寫在每個APP目錄下的models.py內(nèi),寫在其他地方不生效.

使用ORM操作數(shù)據(jù)庫

來編寫一些代碼,models里已經(jīng)默認引入了一個models模塊,自己編寫的表類,必須要繼承models.Model類,就可以成為一個表類.

from django.db import models

class UserInfo(models.Model):
    # 創(chuàng)建一個自增的主鍵
    id = models.AutoField(primary_key=True)
    # 創(chuàng)建一個varchar類型的不能為空的字段
    name = models.CharField(null=False)

之后,需要在命令行執(zhí)行兩個命令來創(chuàng)建數(shù)據(jù)庫:

python manage.py makemigrations
python manage.py migrate

之后一系列的過程結(jié)束之后,回到navicat里可以看到mydata數(shù)據(jù)庫下邊有一堆表,其中有一個名稱叫做login_userinfo表格.這個名字就是APP的名稱下劃線加上類名的小寫,也就是剛才寫的類生成的表.到這里就建立好了Django項目所使用的數(shù)據(jù)庫.

把建立數(shù)據(jù)庫并且配置到Django的使用步驟總結(jié)一下:

  1. 在MySQL數(shù)據(jù)庫里創(chuàng)建一個數(shù)據(jù)庫,名字自定,不用添加任何表
  2. 在Django的settings.py內(nèi)填入數(shù)據(jù)庫的相關(guān)配置
  3. 修改項目的__init__.py, 引入pymysql并且讓其按照MySQLdb的方式工作
  4. 在app下邊的models.py文件中編寫ORM代碼
  5. 執(zhí)行兩個命令,讓Django創(chuàng)建表格.

數(shù)據(jù)的增刪改查

表和數(shù)據(jù)庫就是一種數(shù)據(jù)結(jié)構(gòu),后邊最重要的事情,就是按照設(shè)計好的結(jié)構(gòu),對里邊的數(shù)據(jù)進行操作,比如前端發(fā)回來的數(shù)據(jù)需要更新進數(shù)據(jù)庫,從數(shù)據(jù)庫中取內(nèi)容放到前端去等等.
Django對于數(shù)據(jù)的增刪改查主要是通過對自己生成的表格類的一些特殊操作.

查詢用戶列表并在頁面上顯示出來

接觸查詢數(shù)據(jù)以及進一步的Django頁面模板語言.
首先編寫一個新的功能,去數(shù)據(jù)庫中拿到數(shù)據(jù).

def show_user(request):

    ret = models.UserInfo.objects.all()
    for row in ret:
        print(row.id,row.name)


    return HttpResponse('拿到數(shù)據(jù)了')

這里要記住的是固定用法,也就是類的object.all()方法,這個方法返回的是一個列表,列表的每一個元素是個UserInfo類的對象(也就是一行),對列表里的元素調(diào)用.id和.name,,也就是字段名稱作為屬性,即可拿到具體的值.這個例子里就會打印出數(shù)據(jù)庫UserInfo表里每一行的id和名稱.
那么剩下的問題就是,如何將結(jié)果在頁面上展示出來.由于只能返回一個結(jié)果,顯然不能夠在函數(shù)內(nèi)將數(shù)據(jù)解包出來.這個時候就要用到Django模板語言的循環(huán)功能,即讓Django在替換頁面字符串的時候,動態(tài)的解開數(shù)據(jù)然后生成和替換字符串.我們需要新建一個users.html用于展示用戶列表.

<table class="table-bordered">
    <thead>
    <tr>
        <th>id</th>
        <th>用戶名</th>
    </tr>
    </thead>
    <tbody>
    {% for row in user_list %}
        <tr>
            <td>{{ row.id }}</td>
            <td>{{ row.name }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

這里關(guān)鍵一步,是要了解Django模板語言的循環(huán)功能,{% for row in user_list %}和{% endfor %}之間就是要被循環(huán)的功能,通過看代碼就知道,這里的代碼解析很類似python語言,就是從user_list變量里讀出每一行,然后一行兩列顯示id和name.由于是返回一個頁面,因此還需要對剛才的show_user函數(shù)進行改寫.

def show_user(request):
    ret = models.UserInfo.objects.all()
    return render(request, 'users.html', {'user_list': ret})

這里也是關(guān)鍵的一步,就是返回users.html頁面,同時用和頁面里的同名變量作為鍵,值是對應(yīng)的表格查詢結(jié)果.這樣就可以在users.html內(nèi)看到所有的用戶了.
總結(jié)一下,有三個關(guān)鍵點:

  1. models.UserInfo.objects.all()查詢出全部的行,放在一個列表內(nèi)返回,通過行的字段名可以拿到值
  2. Django的頁面模板語言除了替換特定變量,還可以用循環(huán)指令做類似python的工作
  3. 頁面返回的時候,將查詢結(jié)果直接返回到頁面,由模板語言完成動態(tài)添加內(nèi)容.

新增用戶

通過學(xué)到的查詢知識,可以很容易的想到,ORM模型應(yīng)該還支持各種方法操作數(shù)據(jù),對于目前每一個工作都要實現(xiàn)前后端交互的我們,只需要再編寫一個頁面,讓用戶提交表單,然后將該用戶增加到數(shù)據(jù)庫中,并且可以在剛才的頁面內(nèi)顯示增加后的用戶列表.有了前邊接受并處理表單數(shù)據(jù)的經(jīng)驗,可以很快編寫出函數(shù):

def add_user(request):
    error_hint = ''
    username = request.POST.get('username', None)
    if request.method == 'POST':
        if len(username) > 32 or len(username) == 0:
            error_hint='輸入的用戶名太長或太短'
            return render(request, 'add_user.html', {"error": error_hint})
        else:
            models.UserInfo.objects.create(name=username)
            return redirect("/users/")
    if request.method == "GET":
        return render(request, 'add_user.html')

這個add_user函數(shù)當(dāng)請求是GET的時候,返回輸入名字的頁面,當(dāng)請求是POST的時候,拿到username,符合標(biāo)準(zhǔn)就添加進數(shù)據(jù)庫并且返回當(dāng)前的用戶列表,不符合標(biāo)準(zhǔn)就返回帶有錯誤提示的頁面.
這里的關(guān)鍵是ORM的固定用法.create(name=username),直接將字段名當(dāng)做關(guān)鍵字參數(shù),就可以新建一行數(shù)據(jù)了.
至于web頁面可以簡單的寫一個表單:

<form action="/add_user/" method="post" class="form-horizontal">
    <label for="username" class="col-sm-2 control-label">請輸入新增的用戶名</label>
    <div class="col-sm-4">
    <input type="text" id="username" name="username" >
    </div>
    <div class="col-sm-12">
    <button type="submit" class="btn btn-primary col-xs-offset-4">Submit</button>
        </div>
    <p>{{ error }}</p>
</form>

刪除用戶

在刪除用戶的過程中,將要用到ORM操作數(shù)據(jù)庫的新功能,也就是相當(dāng)于SQL語句的條件語句使用,以及通過GET方式像后端傳遞數(shù)據(jù)的方法來實現(xiàn)刪除.
添加用戶的過程是肯定要讓用戶輸入的,但是刪除用戶如果讓用戶輸入id或者名稱來刪除,則有點過于麻煩,而且用戶名很可能會有重名,因為名稱沒有設(shè)置不能重復(fù).最好的辦法就是將這個操作視覺化,也就是在每行后邊直接添加刪除按鈕,讓用戶所見即所得.但是有個問題,添加的按鈕如何能夠像表單一樣來返回數(shù)據(jù)給后端呢,要為每個按鈕都用一個表單來包裹嗎.這個地方就可以用到通過GET請求發(fā)送數(shù)據(jù)的方法,這樣就無需使用表單,只要使用A標(biāo)簽即可,為了美觀,將A標(biāo)簽通過Bootstrap制作成按鈕一樣的外觀就可以了.
還有一個小知識點,即模板語言for內(nèi)部可以通過forloop.counter來獲得從1開始的for循環(huán)每次的次數(shù),一般可以顯示在表格前邊當(dāng)做序號.根據(jù)這兩個新知識修改HTML文件如下:

<tbody>
    {% for row in user_list %}

        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ row.id }}</td>
            <td>{{ row.name }}</td>
            <td class="text-center"><a href ='/delete_user/?id={{ row.id }}' class="btn btn-default" type="button">刪除</a></td>
        </tr>

    {% endfor %}
{#用a標(biāo)簽做get請求,和post不同,#}
    </tbody>

這里的關(guān)鍵是a標(biāo)簽的href屬性,由于在生成的時候每行可以拿到id,就可以把id加在GET請求內(nèi)一同返回(多個屬性就用&連在一起),這樣后端就可以拿到id對應(yīng)的數(shù)值來操作了.再編寫后端delete_user函數(shù):

def delete_user(request):
    # 取到刪除指定數(shù)據(jù)的id,由于id唯一,通過id給
    user_id = request.GET.get("id", None)
    if user_id:
        try:
            del_obj = models.UserInfo.objects.get(id=user_id)
            del_obj.delete()
        except:
            return render(request, 'users.html',
                          {'user_list': models.UserInfo.objects.all(), "error_on_delete": "用戶不存在"})
        return redirect("/users/")
    else:
        return render(request, 'users.html', {'user_list': models.UserInfo.objects.all(), "error_on_delete": "用戶不存在"})

這里用到的是ORM的新操作方法,就是通過objects.get(id=user_id)來取出所在的那一行(后邊會學(xué)到get方法只能取到一行),然后對這個對象執(zhí)行.delete()方法刪除對象.當(dāng)找不到id的時候,就返回用戶不存在的錯誤.
這樣就完成了一個刪除行的前后端交互方法.刪除按鈕放在表格內(nèi)非常直觀,刪除后的結(jié)果也很方便的可以看到.由于目前只是在寫Django內(nèi)的代碼,還沒有在前端寫JS,實際上通過JS可以將添加和刪除都做在同一個用戶界面里.而且也可以在頁面里不顯示id,因為普通用戶對于id可能不清楚是做什么的,只保留序號即可.

GET和POST方法

在Django 2部分的第二篇文章里提到了GET和POST方法,那時候才剛開始使用GET和POST,現(xiàn)在自己編寫的代碼中已經(jīng)使用過了GET和POST方法,可以來回頭看一看GET和POST方法了.

GET方法的主要用途:

  1. 直接在瀏覽器地址欄輸入URL訪問網(wǎng)站
  2. a標(biāo)簽發(fā)出的是GET請求
  3. 用?key=value&key2=value2傳遞數(shù)據(jù),但是GET請求攜帶的數(shù)據(jù)不能夠超過40K

POST的主要用途:

  1. 向后端提交大段數(shù)據(jù)或者結(jié)構(gòu)化的數(shù)據(jù)
  2. 向后端提交包含隱私的數(shù)據(jù),比如登錄和注冊,支付,各種驗證等
  3. 上傳文件

可見,像剛才的刪除請求,如果不點刪除按鈕,而且用戶已經(jīng)知道了我們的方法,那么可以直接在瀏覽器中輸入對應(yīng)的鏈接,也可以成功刪除指定的數(shù)據(jù).相比接收POST請求然后進行操作,GET請求的私密性要差很多.所以一般還是需要用戶認證登錄等額外手段來保證操作有權(quán)限.

修改用戶名

修改用戶的思路和之前的查找思路非常類似,先找到對應(yīng)id的行,然后修改name為新的值.然后前端需要創(chuàng)建元素用于修改即可.
用剛才相同的思路,即增加一個按鈕用于修改,然后增加一個頁面用于提交,最后用ORM操作數(shù)據(jù)庫.
這里需要注意的是,增加的頁面里設(shè)置input按鈕的內(nèi)容為需要修改的內(nèi)容的默認值,此外在post的時候,還必須要傳遞id,這個時候可以采取在HTML頁面里埋一個隱藏的input框,其值設(shè)置為生成網(wǎng)頁時候的id值,就可以繼續(xù)傳遞了.

HTML頁面的代碼如下:

<div class="container">
    <h1>輸入新的用戶名</h1>
    <form action="/edit_user/" method="post" class="form-inline">
        <div class="form-group">
            <label for="username" class="sr-only control-label "></label>
            <input type="text" class="form-control" id="username" placeholder="Username" name="username" value="{{ edit_obj.name }}">
        </div>
        <div class="form-group">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
        <input type="hidden" value ="{{ user_id }}" name="id">
    </form>
    <div class="row">
        <p class="text-danger text-center col-sm-2">{{ error }}</p>
    </div>

此外,還需要在原來的用戶列表增加一個按鈕,也是帶著id一起返回給edit_user函數(shù).

修改用戶的函數(shù)如下:

def edit_user(request):
    if request.method == "POST":
        new_name = request.POST.get("username", None)
        edit_id = request.POST.get("id", None)
        if len(new_name) > 32 or len(new_name) == 0:
            return render(
                request, 'edit_user.html', {
                    "edit_obj": models.UserInfo.objects.get(
                        id=edit_id), "user_id": edit_id, "error": "用戶名長度為1-32個字符"})

        row = models.UserInfo.objects.get(id=edit_id)
        row.name = new_name
        row.save()
        return redirect("/users/")

    else:
        edit_id = request.GET.get('id', None)
        if edit_id:
            edit_obj = models.UserInfo.objects.get(id=edit_id)
            return render(
                request, 'edit_user.html', {
                    "edit_obj": edit_obj, "user_id": edit_id})

這里引入修改的方法是先設(shè)置好值,然后用.save()方法submit到數(shù)據(jù)庫中.

來源:https://www./content-4-584651.html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多