Django學習記錄

花了2個星期學習了一下Django的基本使用,感覺就是python真的很牛逼,第三方庫真是太豐富了,人生苦短我用python,這句話我是切切實實體會到了。用Django框架寫服務端的代碼,不知道比.net的效率高出多少倍。之前寫.net的時候,爲了把數據庫映射到業務層花大力氣了,又是用EF實體模型,又是用T4模板,從模型層上開始一個接口一個接口的寫到業務層。如今用Django,都是集成的,根本不用管這些,甚至連SQL都不須要會使用,開發速度不知提升多少倍。javascript

這個是個人Django筆記,我聽的老男孩的課,好像是第四期的,16年末的那個版本,兩個大王老師講的仍是很好的。知道了基本使用,接下來就是找個開源項目練一練,練熟了再看看源碼。css

ps. 這是聽得現場筆記,想着本身忘記了回頭看能想起來就行,因此寫的比較零碎。能想到的適合場景就是恰好你也想聽這個課就能夠拿着參考。若是你是想系統的看Django的教程,建議去alex,武沛齊這些大神的博客看,他們寫的是真棒。html

day49

Http:無狀態前端

請求協議的格式java

請求首行.python

Accept:告訴server我能接收的有哪些類型 q是權重的意思mysql

Accept-encoding:壓縮格式,告訴服務器你回覆的壓縮格式jquery

Accept-Language:能接受的語言web

connection:keep-alive 服務器稍微等一下子(默認3000ms),這個也能夠設置成當即斷的模式面試

Host:我訪問的域名,,主機地址

useragent:我這邊的計算機信息啊,瀏覽器信息啊之類的信息,(發給服務器的)

url發送數據的格式:www.baidu.com?username=hhh&pwd=123 就是不安全 數據的數據通常在1k範圍內

get沒有請求體,post纔有,由於get把數據放到後面去了

默認是get的請求方式 a標籤和超連接也都是get請求

post請求

數據再也不地址欄中

數據大小沒有上限

有請求體

若是存在中文,會使用URL編碼

referer:你這個請求從哪裏過來的


響應協議

這個就是server端告訴瀏覽器的一些事情

狀態碼

500 代碼寫錯了

300 定向相關的內容

server:服務器版本信息


寫一個最最簡單的web框架

就是要求寫一個server端,

wsgiref,python內部得服務器,作http解析的

1570799780701

注意那個return後面有個 b 由於要的是字節

1570800053852

environ:服務器打包好了放過來的第一個參數。是一個大的字典。

start_response:就是用來處理請求頭的。

return 返回的就是瀏覽器真正要響應的響應體。

njix(音),真實生產中用這個服務器

1570801103057

根據路徑來調換顯示什麼內容

1570801168682

這個fool是返回的 讀取一個html的內容 注意要加列表的符號 否則會報splite的錯誤

1570801366306

經過字符串讀的時候可能會有問題,這時候能夠考慮先經過字節讀出來,而後轉成字符串。

1570802900739

Django 就是學這4部分的內容

控制器 --url的分發

model--

魔板渲染

view視圖:一個url處理一個函數

MVC MTV

Quit the server with CTRL-BREAK.

model:操做數據庫 ORM的方式

1570804050104

怎麼經過python操做數據庫

怎麼把數據庫的內容更加靈活的渲染到頁面上

這兩點是重點學的也是難點,另外兩點很簡單

經過命令行,建立一個diango項目

1570804682955

mysite2就是一個全局的,這個全局下面有不少的功能。

在這個項目裏面 建一個子項目blog (就好似大的微信微信項目裏有三個獨立的小的功能(朋友圈、聊天..))

至關於把應用分層了,如今這邊說blog博客的應用,那全部的這個功能都在這個裏面了。

1570804929948

1570805069324

pycharm裏面快速的新建一個Django項目

1570805836078

1.在urls裏面 加一個路由 因爲所在的文件夾不一樣 因此須要導入地址

1570806300140

req服務器打包的信息對

return 必定是個httpresponse對象

1570806673898

運行Django的命令

1570806550817

Django的htm文件都往這個文件夾裏面放 若是沒有這個文件夾就本身建

1570806745937

render 函數的第一個必須傳入 request(得對應起來就行) render的功能就是內部作了一個渲染,而後仍是返回httpresponse

1570806896382

setting裏設置路徑拼接

他能自動找到的緣由是在setting裏面作了路徑的自動拼接,因此能找到

1570807115670

Django每次修改自動重啓,不須要再關閉了重啓

1570807317828

1570807378849

放jqueery在static文件夾裏,可是爲了讓這個文件夾的路徑讓Django知道,因此須要到setting裏進行配置。

1570808265481

1570808494695

1570808997166

1571305721629

起別名就是爲了之後方便改動,無外乎就是這個緣由

起了別名就不要用真實的了,用了也沒用,必須用別名

添加Jquerry的方法2 推薦使用

這個方式注意須要在開頭加一個東西。。無論哪一種方式,解析完都是同樣的。

1570865683490

1570865831943

要使用static標籤,首先須要{% load static %}


08:

若是把static那個文件放在blog裏,事實上大點的項目都是這麼玩的。

就該這麼一個 十分方便就是由於有虛擬路徑和實際路徑的幫忙

1570866100429


無命名分組

1570870446216

1570870480183

1570870634977

1570870706500

只有分組的纔會有參數更他對應,不加括號的確定沒有參數和他對應


有名分組

?P<>起有名分組 ==這個是老版本的了,注意DJ2.0以後就不是這麼玩的了==

1570871061897

1570887244243

人家在前端起好什麼名字,你這邊就得叫什麼名字

1570871133157

1570871196644

1570871293814


提交註冊

首先經過url進入regist

1570872383302

而後寫完後,點擊提交,這個前端訪問一個連接,這個連接仍是指向了regist

1570872515193

能夠經過一個視圖作兩件事,只要他們的方式不一樣就行

1570872648547

同源的概念

1570873014959

url部分別名的一個概念

==這個reg對應上能夠這麼理解:在html裏寫的時候就是在找 這個表單的信息給服務器的哪一個函數去執行呢(這個函數確定往前就是對應的一個連接了),,而後後端path(URL)那邊氣的別名,就是指示那個去執行表單提交過來的信息的函數==

1570873299123

1570873446835


09 URL的分發

URL如今都在全局的一個項目裏面了,若是項目多了就很差使了。沒有一個很好的解耦。

但願全局作一個分發,發到我的。

1570873610597

1570873824700

1570873860376


day50

01 視圖函數的介紹 view

1570929275271

​ 推薦使用render問題少。。瞭解下面那個方法,由於其餘人用

1570929632540


把局部變量轉換成鍵值對的locals,

request也是局部變量,因此也能夠傳過去,還能夠用裏面的屬性

1570929933963

1570930098207


跳轉函數:redirect

從一個視圖裏作完了須要去另外一個頁面,就用這個

1570930534195

跳轉和直接render的區別:

1570931553669


03 Django魔板之變量

模板的組成:HRML代碼+邏輯控制代碼

邏輯控制代碼的組成

pycharm裏面搞到shell的方法

1570934006642


這個render到底隱藏了哪些?

日後面傳不必定是字符串,列表啊 字典啊 類啊 均可以滴 萬能句點符號

1570933908055

1570934864213

1570934994409


04 魔板之過濾器

內置函數 處理字符串方便一些

1570935697914

1570935919214


05 魔板控制語句的使用

1570937062601

計數器

1570937395356

各類計數器

1570937741470

1570937851908

遍歷到某個元素若是是空的時候作出什麼處理

1570939088538


06.標籤tag補充

1570941729179

Django第一次post是禁止的,除非帶着身份驗證的token數據。

這個流程就是用瀏覽器訪問的時候會把這個祕鑰發過來,,而後post提交的時候會帶着祕鑰一塊兒去

1570941942355


07 莫模板之自定義filter和simple_tag

1570942597020

1570943005965

這個整完了得重啓一下,好像是路徑不能自動的更新

這個傳的變量的個數,就是一個,若是要多個,那就弄個列表

1570943436002

1570943136741

1570943378583

自定義標籤的參數不限制,能夠有多個

1570944145144

1570944213099

1570944308632

1571308294549


08 模板之繼承標籤 就是不停的寫盒子

建一個新的Django

1571023561104

先搭出一個這樣的框架

先寫一個基礎了html,裏面分塊,這個塊就是能夠修改的。

1571023632076

1571024742422

字版的第一句話就是集繼承過來

1571024934515

1571025020546

1571025328319

include添加

1571030204119

1571030257641

day51 數據庫

01 數據庫表與表之間一對多多對多的關係

多對多的關係用三張表

1571055431197

一對一,兩張表怎麼弄

1571055800223

其實數據庫只是提供了一對多的關係,多對多的關係個一對一的關係都是從一對多的關係上改過來的。

02 Django的ORM概念

ORM 對象關係映射表

經過python的類對數據路的表進行操做

1571057118544

==建立數據庫的兩個語句==

makemigrations 和 migrate

D:\Python37\python37.exe manage.py makemigrations (這一步只是建立了一個腳本,並無和數據庫打交道,在blog下的migration文件夾裏建立的腳本)

D:\Python37\python37.exe manage.py migrate

1571057611870

1571057729689

默認是鏈接sqlite數據庫,若是是要鏈接mysql數據庫,須要在設置裏作一些修改

1571058184778

1571058651897

鏈接mysql是修改修改成pymysql引擎

1571058526719


03 ORM中的增刪改查操做

改動一下表的字段

1571060022876

1571060143222

1571060430508


方式一:

1571060983078

方拾二:

1571061645096

1571061745398


法一 :這種方法是能夠同時改多個的 。這種update的方法效率高,單對單,就改一個。

1571062887808

法二 :這種方法只能改一個 save效率低,由於沒有改動的也會給更新一下

1571063632244

經過設置,打印出ORM執行時所使用的sql語句的日誌

1571063905090

1571063956886


刪除

1571064030382


04 ORM查詢API

1571064667810

1571064887376

1571065036632

1571065131768

1571065864783

1571110972153

1571112798279

1571112860273

1571112489708

雙下劃線的特殊功能,模糊查詢

1571113118015

day52 ORM多表操做

外鍵關聯時的2.0版本新注意點

一個2.0版本的新要求,視頻的版本沒有這個

1571140551660

02 多表操做之一對多查詢之對象查詢

1571114129453

一對多的直接點出來確定是一個對象

1571114181667


涉及到外鍵的一些查詢

方法一: 有點麻煩

1571115001198

方法二

publish找book表關聯的內容

1571133437404

1571134035850

==這個後面接04 03是補充的,有些錯亂==

03 一對多增長記錄

publish加上引號就是按照映射關係去找,也就是加載完去找,因此能夠publish這個類放在book這個類的哪裏都行。可是若是publish不加上引號,那就是按照變量關係去找的了,那麼publish這個類就得放在book這個類的上面。

1571144538222

1571144969531

1571145675768

1571146262982

04 ORM多表操做之基於雙下劃線查詢

上承接02,多表查詢的任務(找符合外鍵條件的一個任務)

1571147394346

1571147659689

1571147808891

1571148118742

05 多對多添加記錄

推薦自動帶的那個方式 manytomany

多對多前提是有兩張多對多的表

1571150744030

1571151188820

1571152371210

1571152756334

1571152835168

1571153516409

==上述第三個表(本身寫的那個表)的方法不經常使用,這個多是一家之言,主要是以爲麻煩==

1571153681831

06 多表操做之多對多聚合查詢

1571208661470


聚合函數

1571209053077

1571209134233

1571209414526


分組

能夠理解爲:先分組,而後sum是對每一個組進行操做

1571210030016

1571210508567

07 ORM多表操做之F查詢與Q查詢

1571211414655

1571211592172

1571213270379

1571213181791

08 ORM的querySet集合對象的特性

1571213711949

1571214258243

1571214591329

生成器的做用就是:節省內存

數據量很少還反覆要用的話,緩存就行。

若是數據量萬級別以上,仍是建議用迭代器

1571215101871

day53 admin,cookies,session

01 admin的介紹

Django牛逼的組件

url

views

models

templates

admin

1571217241501

1571218005897在、

註冊->建立超級用戶->在頁面裏看

03 自定義admin樣式

admin關於數據庫的後臺管理

如今想在原來的上面橫着顯示一堆字樣 ,,須要先寫已給類,,而後告訴admin

1571225329198

1571225488966

1571225496395


1.讓框子變的可修改

2.listdisable裏不能加多對多的關係

1571225772183


1571226268653

1571226386813


1571227063578

1571227152749


1571227317110

1571227505595


1571229415727

顯示字段的時候換個別名

1571229574265

按照某個字段排序

1571231917235

1571232068670

1571232283266

05 cookie介紹

1571238923614

1571239109105

06 cookie和session的配合使用

cookie和session都有默認放在某個表裏的,因此若是要用這個你就須要把這個表給初始化出來。(用migrate的那些指令)

若是隻有一個cookie的話,全部信息都放在客戶端,不安全,容易被竊取。

cookie就像是客戶端的錢包

session就像是服務端的錢包

session在Django裏會默認存到數據庫裏

若是排除安全和你不嫌棄來回傳輸慢的化,cookies也是能夠本身完成這些功能的,事實上人們一開始也是這麼作的,後來拿session來解決cookies遇到的問題的。 我把鑰匙(cookies)給你你下次帶着鑰匙來,用戶的哪些資料(session對應的東西)我都放在數據庫裏面。拿着鑰匙打開了數據庫的內容。

1571295707891

1571288069245

1571288219542

1571288402664

1571296198353

1571296363496

1571296573927

1571296703290

登陸的時候若是用戶名和密碼對應上了,那就把兩個關鍵字(islogin和user)存到session裏。每次登陸index頁面的時候都去看一下session裏(按照islogin鍵去找)的islogin是否是爲true,若是是true就繼續往下走,若是不是true那就返回登陸界面,讓用戶登陸。

def login(request):
    print("cookies",request.COOKIES)
    print("sessions",request.session)

    if request.method=="POST":
        name=request.POST.get("user")
        pwd=request.POST.get("pwd")
        print("name=======",name)
        print("pwd==========",pwd)
        if name=="yuan" and pwd=="123":#這邊在假設若是登陸成功了
            #若是登陸成功了,就給這兩個保存起來
            #session會自動把這個存到數據庫裏面。
            request.session["is_login"]=True
            request.session["user"]=name
            return redirect("/index")
    return render(request,"login.html")#若是沒有登陸成功,就是還返回其login的界面

def index(request):
    if request.session.get("is_login",None):
        name=request.session.get("user",None)
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!",name)
        return render(request,"index.html",{"name":name})
    else:
        return redirect("/login")

day54 Django請求生命週期

04 複習以前的內容

在pycharm裏給Django再建一個app

05 請求生命週期之Http請求

1571312491189

1571312753730

Django的請求的生命週期是什麼?

生命週期指的是用戶在瀏覽器上一點,在你的瀏覽器上都發生了什麼。---

這個是簡單的流程

1571319376862

06 CBV的寫法

路由分發裏是個類CBV式的編程

1571317285625

1571315754722

07 CBV擴展

找到類後,不會首先執行get或post方法,而是執行繼承的view裏的那個dispatch方法,dispatch方法幫助咱們反射找到要執行的get仍是post方法。

渲染完的頁面返回的時候,也是先返回給dispatch而後再返回給用戶。1571316563126

1571317199032

08 瞎扯淡

09 響應內容

加響應頭

1571319283910

10 響應內容二

完整的建一個Django文件

1571319799864

1571319741136

1571319731040

11 學管-數據庫設計

1571320915119

1571321204500

12 班級管理 單表操做

1571322702712

1571322816303

1571323082383

1571323018802

1571323269330

1571323506332

1571323635412

1571323691344

1571323951178

1571324455513

1571324388751

1571324572682

1571324734998

1571324822159

1571324845057

1571325044508

1571325125646

這邊還得加一個token鑰匙,否則post不過去

1571325277314

1571381957453

13 學員管理,多表操做

1571385582998

1571386097918

day55 Django學員管理示例1

01 複習ORM基本操做概要

單表的CRUD

1571403181811

一對多的CRUD

1571404543386

filter和values的跨表都是經過雙下劃線來實現的

1571404393885

多對多

1571405604373

1571405715130

1571405887200

1571406004790

1571406454516

02 一對多補充

找學生屬於哪一個校區,,跨多個表

1571410385350

1571411599184

03 一對多補充二

反向查找默認是字段_set_這種形式,是能夠改的。

1571560465377

1571560699919

1571561015604

1571561141211

04 編輯學生

這集沒啥特別的重點,一個是一對多表的CRUD,還有一個就是模板語言裏怎麼將下拉列表的框框變成默認的,就是怎麼checked。

05 多對多補充 CRUD

1571564944106

1571565102028

若是定義了related_name,就經過related_name對它進行反向操做

1571565275082

1571566104048

總結一下

1571566182488

06 多對多補充二 跨表

感受不到第三張表的存在,這就是manytomany的魅力。

多對多的反向必須加上relatedname,,不加就不能反向查了。

1571566893147

1571567033523

加了value就是數字了,就不能再點了

1571567258743

07 爲班級分配老師

1571573032928

1571573244153

1571573718339

1571573828273

1571574398790

1571657975050

1571574872983

1571575002984

1571575091602

08 Ajax的簡單應用

1571575859125

1571576054932

1571576131133

1571576706398

1571577354021

1571577806339c

09 Ajax刪除學生

1571660626875

1571661081703

1571661178052

day56

03 bootstrap和fontawesome製做界面

bootstrap

對static裏面的內容分個類

1571661659767

1571662030434

1571662119019

1571662218022

1571663627202

1571663746198

1571664115888

http://fontawesome.dashgame.com/ 專業圖標 注意下面的使用方法

1571669100053

1571669466977

經過寫ID綁定觸發的方式把按鈕和模態關聯起來。

1571711797881

選兩個標籤的時候注意這個寫法啊,一個引號裏面寫逗號

1571726271408

1571726276134

1571726427458

無心中調試出的一個知識點

1571737247454

1571733375745

1571726699277

1571733633264

1571727276487

1571728345841

1571728427161

06 建立學生信息二

1571743437024

1571744650017

須要值得注意的是:可能會出現,剛開始加頁面時給全部的控件都綁定了事件,而後再ajax添加新的表單行後忘記給行裏面的控件添加新的事件(57-bug修復)

解決方法,用事件委託來解決,何時點擊,何時綁定。

1571752857221

1571747376833

1571753749329

1571747400623

day57

01 複習

1571746091268

1571746413185

02 學生管理系統編輯學生信息以前端功能

方式一:

1571748035785

1571748343061

方式1的缺點就是,和格子的對於關係太嚴格了。要是再增長一列就完犢子了。


方法二:

1571750300653

1571817701534

方法二的思想就是經過給每個td上增長一個屬性,而後經過js對各個表格進行精準的操做。這樣的好處就是即便外面的再增長或者刪除或調換一列,這個js代碼都不須要大換。

<div class="container">
    <table class="table table-bordered table table-striped" id="tb">
        <thead>
        <th>姓名</th>
        <th>性別</th>
        <th>年齡</th>  
        <th>班級</th>
        <th>操做</th>
        </thead>
        <tbody id="tb">
        {% for row in stu_list %}
            <tr nid="{{ row.id }}">
                <td na="user">{{ row.username }}</td>
                <td na="gender">{{ row.gender }}</td>
                <td na="age">{{ row.age }}</td>
                <td na="cls_id" cid="{{ row.cs_id }}">{{ row.cs.title }}</td>
                <td>
                    <a href="del_students.html?nid={{ row.id }}">刪除</a>
                    |
                    <a class="edit-row">編輯</a>
                </td>

            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
function bindEditStudent() {
        $("#tb").on("click",".edit-row",function () {
            {# 首先把那個增長的模態頁面給打開 #}
            $("#editstudentmodal").modal("show");
            {# 打開後就要在這個上面去顯示選中的那一行的值 #}
            {# 取出那一行每一個小個子td裏面的值 #}
            $(this).parent().prevAll().each(function () {
                {#對那一行裏的每個元素進行輪詢#}
                var v=$(this).text();
                var n=$(this).attr("na");
                console.log(v)
                if (n=="cls_id")#特殊的特殊處理吧,這個須要拿到的是對於班級的id。。
                {
                    //爲了這個特殊處理,在html裏給這個增長了cid屬性
                    var cid=$(this).attr("cid");{#拿到了這個學生對應的班級的id#}
                    $('#editmodel select[name="cls_id"]').val(cid);
                } else if(n=="gender"){ 
                    //性別也特殊,是單選按鈕,經過
                    if (v==true){
                        $("#editmodel :radio[value='0']").prop("checked",true);
                    }else {
                        $("#editmodel :radio[value='1']").prop("checked",true);
                    }
                }else {
                    //n=age
                    //v=12
                    $("#editmodel input[name='"+n+"']").val(v);
                }

            })
        });
    }

這張圖的cid沒有賦值,看下一張

1571751213108

1571751260902

05小總結

增長,編輯的時候建議使用普通的刷新頁面的方式,刪除的時候建議使用ajax的方式

1571818703788

6 ajax功能之dataType和traditional

1571819162204

1571819504464

1571819251631

1571819329039

若是非要發字典,把字典用json變成字符串日後發

1571819402853

day58

1571827052411

04 分頁的基礎知識

1571828183403

05 內置分頁的用法

1571828471865

1571829878251

1571828982250

1571829772947

1571829963837

def index(request):
    userList=[]
    for i in range(1,1000):
        temp={"name":"root"+str(i),"age":i}
        userList.append(temp)
    current_Page=request.GET.get("p")#當前想要獲取哪一頁
    paginator=Paginator(userList,10)#傳入總共的個數,和一頁顯示多少個
    try:
        posts=paginator.page(current_Page)
    except PageNotAnInteger:
        posts=paginator.page(1)
    except EmptyPage:#當向page()提供一個有效值,可是那個頁面上沒有任何對象時拋出
        posts=paginator.page(paginator.num_pages)
    return render(request,"neizhifenye.html",{"posts":posts})
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    {#把後端傳過來的列表循環的顯示出來#}
    {% for item in posts.object_list %}
      <li>{{ item.name }}-{{ item.age }}</li>
    {% endfor %}

    {% if posts.has_previous %}
        <a href="neizhifenye?p={{ posts.previous_page_number }}">上一頁</a>
    {% endif %}
    {% if posts.has_next %}
        <a href="neizhifenye?p={{ posts.next_page_number }}">下一頁</a>
    {% endif %}


</head>

06 擴展內置分頁的一些功能

1571832693201

1571832797460

對Django自帶的分頁功能進行擴展後,前端和後端部分關鍵代碼

這個可使用include形式,就是在前端頁面把頁碼選擇的那一行數據放到一個include的文件夾裏,須要用的時候調出來用。。這樣增長前端代碼的複用率。

{% for item in posts.object_list %}
      <li>{{ item.name }}-{{ item.age }}</li>
    {% endfor %}

    {% if posts.has_previous %}
        <a href="neizhifenye?p={{ posts.previous_page_number }}">上一頁</a>
    {% endif %}

    {% for i in posts.paginator.paper_num_range %}  //這邊注意先.出paginator 再paper_num..
        {% if i == posts.number %}  {# 到了當前頁的給大寫一下 #}
            <a style="font-size: 30px;" href="neizhifenye?p={{ i }}">{{ i }}</a>
        {% else %}
            <a href="neizhifenye?p={{ i }}">{{ i }}</a>
        {% endif %}
    {% endfor %}

    {% if posts.has_next %}
        <a href="neizhifenye?p={{ posts.next_page_number }}">下一頁</a>
    {% endif %}
#擴展內置分頁的一些功能
class CustomPaginator(Paginator):#繼承於原理的paginator類
    def __init__(self,current_page,per_pager_num,*args,**kwargs):
        self.current_page=int(current_page)#當前頁
        self.per_pager_num=int(per_pager_num)#一頁顯示多少條
        super(CustomPaginator,self).__init__(*args,**kwargs)
    def paper_num_range(self):#這個就是擴展的那個功能
        #self.num_pages 總共的頁數  這個參數是從父類那裏繼承過來的
        #self.current_page  當前頁(就是瀏覽器申請訪問的那個頁面)
        #self.per_paper_num  最多顯示頁碼的數量
        if self.num_pages<self.per_pager_num: #若是總共須要的頁數還比下面顯示出來的頁數少
            return range(1,self.num_pages+1)   #那就把總共的頁數都顯示出來
        #若是總共須要的頁數特別多
        part=int(self.per_pager_num/2)  #拿到下面一共要顯示多少欄的一半的值
                                        #好比下面要顯示11個  那就取通常5個

        if self.current_page<=part:   #若是當前要顯示的頁碼 比通常要寫
            return range(1,self.per_pager_num+1) #這種狀況就是  你如今要第2頁,下面顯示11個跳轉頁面的按鈕
                                                  #那就應該顯示1--11

        if (self.current_page+part)>self.num_pages:#這種狀況就是最後那幾個  當前要的頁面 已經很接近最後那幾個了,這時候就顯示倒數後面幾個就行
            return range(self.num_pages-self.per_pager_num+1,self.num_pages+1)

        #若是上面的if都沒有能經過,那就是最最普通的通常狀況了
        return range(self.current_page-part,self.current_page+part+1)

def index1(request):
    userList=[]#模擬要顯示的東西
    for i in range(1,1000):
        temp={"name":"root"+str(i),"age":i}
        userList.append(temp)

    cuurent_page=request.GET.get("p")
    paginator=CustomPaginator(cuurent_page,7,userList,10)
    try:
        posts=paginator.page(cuurent_page)
    except PageNotAnInteger:
        posts=paginator.page(1)    #若是取到的不是整數,那就默認顯示第一頁
    except EmptyPage:#若是是空頁面 說明過界了 那就顯示最後一頁
        posts=paginator.page(paginator.num_pages)
    return render(request,"neizhifenye.html",{"posts":posts})

08 Django的form組件

這個裏面的名字(user pwd)必須和前端提交過來的同樣(也就是required.post)裏面存儲的同樣才行。這樣Django纔會有辦法自動識別去找了比較。

1571833718045

1571834729543

1571835091662

1571835183467

1571914135781

代碼:

後端代碼

from django.shortcuts import render ,redirect,HttpResponse
from django import forms
from django.forms import fields
class F1Form(forms.Form):
    #對form表單裏的數據類型進行限定
    #注意這個名字不能瞎寫,須要和前端傳過來的那個同樣
    user=fields.CharField(max_length=18,
                          min_length=3,
                          required=True,
                          error_messages={"required":"用戶名不能爲空",
                                          "max_length":"太長了",
                                          "min_length":"過短了",
                                          "invalid":"..",#全部的格式錯誤關鍵字都是invalid
                                          }
                          )
    pwd=fields.CharField(min_length=6,required=True)
    age=fields.IntegerField(required=True)
    email=fields.EmailField(required=True)
def form(request):
    if request.method=="GET":
        obj=F1Form
        return render(request,"form.html",{"obj":obj})#這個地方傳過去是由於能夠利用這個本身生成#                                                      #HTML
    if request.method=="POST":
        obj=F1Form(request.POST)#這個地方特別注意是request.POST而不是request否則會報isvalid的錯誤
        #是否所有驗證成功
        if obj.is_valid():
            #print("驗證成功",obj.cleaned_data)
            return redirect("http://www.baidu.com")
        else:
            print("驗證失敗",obj.errors)
            return render(request, "form.html", {"obj": obj})

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form id="fm" action="formtest" method="post">
         {#前端利用了傳來的form對象自動生成HTML#}
        <p>姓名{{ obj.user }}{{ obj.errors.user.0 }}</p>
        <p>密碼{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
        <p>年齡{{ obj.age }}{{ obj.errors.age.0 }}</p>
        <p>e-mail{{ obj.email }}{{ obj.errors.email.0 }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

day59

當天的課上筆記

參考博客:                
http://www.cnblogs.com/wupeiqi/articles/6144178.html

Form
    1. 驗證
    2. 生成HTML(保留上次輸入內容)
    3. 初始化默認是

Form重點:
    - 字段
        用於保存正則表達式
        ChoiceField *****
        MultipleChoiceField
        CharField
        IntegerField
        DecimalField
        DateField
        DateTimeField
        EmailField
        GenericIPAddressField
        FileField
        
        RegexField
    - HTML插件
        用於生成HTML標籤
        
    - 特殊的單選或多選時,數據源是否能實時更新?????*****
        from app01 import models
        class LoveForm(forms.Form):
            price = fields.IntegerField()
            user_id = fields.IntegerField(
                # widget=widgets.Select(choices=[(0,'alex'),(1,'劉皓宸'),(2,'楊建'),])
                widget=widgets.Select()
            )

            def __init__(self,*args,**kwargs):
                super(LoveForm,self).__init__(*args,**kwargs)
                self.fields['user_id'].widget.choices = models.UserInfo.objects.values_list('id','username')
                
        from django.forms.models import ModelChoiceField
        from django.forms.models import ModelChoiceField
        class LoveForm(forms.Form):
            price = fields.IntegerField()

            user_id2 = ModelChoiceField(
                queryset=models.UserInfo.objects.all(),
                to_field_name='id'
            )
        
        注意:依賴models中的str方法

01 form組件

取數據和保存到數據庫的方式

cleand_data就是獲取傳過來的數據

更加簡潔的方式往數據庫裏存儲數據

1571914358875

1571914798312

get請求後在userform裏面設置默認值,這樣返回到頁面渲染後,控件就是有默認值的了

1571915210011

02 form組件之字段

經過用這個組件,能夠定製更多的HTML標籤

1571919111554

1571916212179

這個select就是多選的下拉框

1571916465133

1571916730087


兩種設置控件默認值(也就是這個控件在頁面上顯示什麼值)的方法

  • 一種是建立form對象的時候傳,這個時候能夠初始化全部的控件值

  • 一種是建立控件的時候傳,這個時候只能初始化所在的這個控件的值

1571916969553


一句話生成全部控件的方法,不推薦這兒作,由於雖然方便,可是調整樣式的時候就麻煩了。

1571917618070


form表單傳輸文件的時候須要加上這句話,否則文件傳輸不過來的

1571919442652

1571919608275


單選框和多選框給默認的初值

1571919958561

1571920342623

1571920459939


用的不算太多,不知道用在什麼場合

1571921046102

1571921032630

1571921454403


1571922083652

這些本質就是幫咱們作了正則表達式的封裝

04 form組件字段詳解3

每個field裏面都封裝了一個正則表達式 + 一個默認插件。。這個默認插件就是在_str裏,_str就是調用的時候輸出的那個文本。

1571925101008


額外插的一個知識點:後端往前端傳輸一個字符串,怎麼就能讓前端知道這個字符串的意思不是普通的字符串,而是表明的HTML標籤呢。

1571925325273

1571925515095

1571925944140

1571926431646

1571926532826

1571928905796

1571929996072

day60

複習:簡單的擴展就是若是自帶的正則表達式已經不能知足你的需求了,那麼如何擴展或者是說本身定義正則表達式,有多是多個正則表達式來驗證。

複雜的擴展就是對內容進行一些判斷了,若是內容已經有了,那怎麼弄。

課上筆記

1.簡單擴展
        利用Form組件自帶的正則擴展:
            a. 方式一
                from django.forms import Form
                from django.forms import widgets
                from django.forms import fields
                from django.core.validators import RegexValidator
                 
                class MyForm(Form):
                    user = fields.CharField(
                        error_messages={'invalid': '...'},
                        validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')],
                    )
            b. 方式二
                from django.forms import Form
                from django.forms import widgets
                from django.forms import fields
                from django.core.validators import RegexValidator
                 
                class MyForm(Form):
                    user = fields.RegexField(r'^[0-9]+$',error_messages={'invalid': '...'})
                    
    2.基於源碼流程
        a. 單字段
            from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
            class AjaxForm(forms.Form):
                username = fields.CharField()
                user_id = fields.IntegerField(
                    widget=widgets.Select(choices=[(0,'alex'),(1,'劉皓宸'),(2,'楊建'),])
                )
            # 自定義方法 clean_字段名
            # 必須返回值self.cleaned_data['username']
            # 若是出錯:raise ValidationError('用戶名已存在')
            def clean_username(self):
                v = self.cleaned_data['username']
                if models.UserInfo.objects.filter(username=v).count():
                    # 總體錯了
                    # 本身詳細錯誤信息
                    raise ValidationError('用戶名已存在')
                return v
            def clean_user_id(self):
                return self.cleaned_data['user_id']
                    
                 
        b. 總體錯誤驗證
            class AjaxForm(forms.Form):
                username = fields.CharField()
                user_id = fields.IntegerField(
                    widget=widgets.Select(choices=[(0,'alex'),(1,'劉皓宸'),(2,'楊建'),])
                )
                # 自定義方法 clean_字段名
                # 必須返回值self.cleaned_data['username']
                # 若是出錯:raise ValidationError('用戶名已存在')
                def clean_username(self):
                    v = self.cleaned_data['username']
                    if models.UserInfo.objects.filter(username=v).count():
                        # 總體錯了
                        # 本身詳細錯誤信息
                        raise ValidationError('用戶名已存在')
                    return v
                def clean_user_id(self):
                    return self.cleaned_data['user_id']

                def clean(self):
                    value_dict = self.cleaned_data
                    v1 = value_dict.get('username')
                    v2 = value_dict.get('user_id')
                    if v1 == 'root' and v2==1:
                        raise ValidationError('總體錯誤信息')
                    return self.cleaned_data
                    
                    
        PS: _post_clean

01 form表單的回顧

如何把一個表單序列化,而後用ajax的方式傳輸出去

image-20191026160159424

image-20191026161159400

image-20191026161442605


是什麼致使了這個不是python內部的數據類型卻可以轉換成json,是由於他繼承於dic

image-20191026163429709


02 在form裏自定義方法

規則:自定義方法clean_字段名,必須返回值self。cleaned_data[「username」],若是出錯:raise validationerror(「用戶名已經存在」)

這個本身寫clean函數須要有返回值,由於源碼裏是拿到返回值從新賦值給data。。

本身的感受:這兩步的意思就是先檢查格式,再檢查內容。檢查格式的人家已經給寫好了正則表達式,

檢查內容內容的須要本身去寫,本身去寫的過程當中注意去知足別人的格式。

image-20191026172843245

image-20191026172957910

image-20191026175128208 導入validation的命名空間

image-20191026174700082

image-20191026175052829

03 全局校驗的鉤子

有時候進行驗證須要用到不少的前面傳過來的數據,這個時候放在單一的那個變量裏顯然顯得十分的不合適,

這個時候就須要咱們在全部的單一的執行完了以後,再有一個能夠執行全局的校驗的函數。

image-20191026182031247

image-20191026182037704

05Django的序列化

把某種東西可以保存在文件裏的過程,叫作序列化

這種[ob,obj...]的只能經過Django給的那種方式進行序列化

image-20191026202925313

這個裏面的data數據至關於被序列化了兩次,那麼前端也要解兩次。 success回調的那個arg至關於已經幫忙解開一次了,裏面只要再解開一次就行。

image-20191026203336008

經過values獲取的時候怎麼轉換成json的格式

image-20191026204148150

總結來講,返回的是對象的時候採用內置的序列化方法,而後前端也要反序列化兩次

Django序列化
    a.對象    ----用內部的
    b.字典
    c.元祖
    
序列化:在JavaScript裏用的是:JSON.parse() ,JSON.stringfy()
Django裏 json.dumps()和json.load() 這種python內置的序列化只能處理python內置的數據類型。爲了解決
這個問題,用Django給提供的序列化一下,而後再總體序列化一下。意思就是那個不是數據類型的地方序列化的2次,因此前端那邊也反序列化2次。
        Django:
            json.dumps()
            json.loads()
            問題:
                serilize:  model.TB.objects.all()
                
                json:  list(model.TB.objects.values())
                json:  list(model.TB.objects.values_list())

day61 ==聽的不在狀態==

01 回顧

  • ajax的日後臺傳時value不能是字典,若是非要傳字典,能夠先把這個字典轉化爲字符串再傳輸過去。
  • serilize就是將ajax的表單序列化,傳給後臺,這樣比較方便

image-20191028144052294

內容回顧:
    1.ajax參數  
        url:
        type:
        data:
            1. value不能是字典 {k1:'v1',k2:[1,2,3,],k3: JSON.stringify({})}
            2. $('').serilizer()
        dataType:"JSON",# text,html,xml
        單詞太長了 traditional:
        success:function(arg){
            # arg=>obj
        },
        error:function(){        
        }
    2. 序列化
        JavaScript:
            JSON.parse()
            JSON.stringify()   
        Django:
            json.dumps()
            json.loads()
            問題:
                serilize:  model.TB.objects.all()
                
                json:  list(model.TB.objects.values())
                json:  list(model.TB.objects.values_list())    
    3. Form
        做用:用於驗證+(生成HTML+保存上次提交的數據)
        使用:
            1.建立類
            2.建立字段()
            3. 驗證用戶輸入:
                obj = Form(request.POST,request.FILES)
                if obj.is_valid():
                    obj.cleaned_data
                else:
                    obj.errors
            4. clean_字段
            5. clean()  _post_clean()
         
            PS: __all__              
    4. 分頁組件
        a. 內置
        b. 擴展
        c. 自定義
    5. XSS攻擊
        跨站腳本攻擊:
            
        防止:
            - 其餘人輸入的內容     不用safe
            - 本身輸入的內容       可用safe
        
        
        <script>
            for(var i=0;i<9999;i++){
                alert(i)
            }
        </script>
        
         
        <script>
            獲取本地cookie,發送到另一個網站
        </script>
        
        
今日內容:

    - 文件上傳
        - 普通上傳
        - 自定義頁面上傳按鈕
        - 基於Form作上傳
        - Ajax上傳文件?????
        
    - Django Model操做補充
        參考博客:http://www.cnblogs.com/wupeiqi/articles/6216618.html
        1. 建立類
            class UserInfo(model.Model):
                
                age = CharFiled(是否爲空,類型,長度,列名,索引=True||||錯誤提示,自定義驗證規則)
                ..
                ..
                
                ### 一對多
                ### 一對一
                    - 
                
                
                ### 多對多
                    - 第三張表:a.自動建立;b.手動建立; c. 手動+自動
                
                    ### 自關聯:互粉 ###
                    
            a. 索引
            b. 一對多: on_delete
            c. 一對一和一對可能是什麼關係? unique=true
            d. 多對多:
                - a.自動建立;b.手動建立; c. 手動+自動
                - ### 自關聯:互粉 ###
                
            PS:related_name
            
        2. 操做類
            obj = UserInfo.objects.all().all().all()

02 上傳文件 image-20191028151445170

image-20191028151758778

image-20191028152139850

image-20191028152419956

上傳的圖標的製做

image-20191028155054229

image-20191028155423984

image-20191028160007564

08 數據庫拾遺

image-20191028170231001


三種索引

  • 一種是隻能加速查找
  • 一種是除了加速查找 還能保證惟一
  • 一種是除了加速查找保證惟一以外 還不能爲空

image-20191028172530292

image-20191028172614838


對admin進行一些操做

image-20191028173405451

image-20191028173518783


對外鍵刪除的時候作一些設置 就是你刪除關聯的時候其餘人會怎麼反應

image-20191028175954636

image-20191028181233107

image-20191029103831084

image-20191029104118847

聯合惟一,就是好比給一我的打標籤 一種標籤只能打一次對一我的

image-20191029105146508

這樣寫就能夠經過m對這個操做了。本身定義第三張表,m的add和set就不能用了,filter還能夠用。

這樣容易亂,不是很推薦

image-20191029113111867

11 強插的面試題

image-20191029110701804

image-20191029111752441

image-20191029115639068

必須的要會的

image-20191029144658379

ps:推薦寫relatedname


image-20191029150214193

image-20191029150345043

下面可能會出現跨表操做的時候就加上related,加一個或者加兩個都是能夠的。

image-20191029150826455


image-20191029151206940

image-20191029151330171

image-20191029151550294

using指定鏈接哪一個庫

image-20191029154249972


兩個js面試題

image-20191029155610002

題1:代碼在執行前做用域已經建立,執行的時候按照做用域去找值就對了

返回inner函數沒有拿到外面來,不拿,人家在編譯的過程當中做用域就已經生成了。result是代指inner函數,inner函數有本身的做用域

image-20191029160928439

因此第一個題目的答案是456

第二題:
js裏沒有類,通常用函數來充當類,函數充當類的時候,通常默認把函數名的首字母大寫。

image-20191029165531467

image-20191029170011779

==後面關於數據庫的很對操做沒有看,有點複雜,用過一段時間後再回來看==

這個建議去武沛齊的博客上看

day62

02 發送ajax的jQuery方式和自帶的方式

image-20191029180018566

image-20191029193802373

image-20191029194418371

這樣發過去會有一個問題,Django的後臺不知道這個究竟是get仍是post,沒法解析出這個body裏面的數據

因此就會發現post和get裏面沒有數據,可是body裏面有數據。

image-20191029195059608

image-20191029200825525

03 僞發送ajax的方式

image-20191029201955546

基於ireame和form表單實現的僞造ajax

form提供數據 irame提供通道 把數據發過去

image-20191029202451459

image-20191029202751275

irame的兼容性是最好的

不用動態綁定會出現的一個問題就是,重上到下進行刷新的時候可能會出現上面的用到下面的函數,可是尚未刷新到下面的函數的狀況。

image-20191029203555439

image-20191029205035515

image-20191029205542170

在標籤上綁定的時候那個this爲window,動態綁定this不要傳遞,由於內部的那個就是當前標籤

image-20191029214651658

image-20191029214725247

image-20191029215028673

image-20191029220204995

11 jsonp跨域

jsonp是一種方式,添加到scrapt塊裏,而後在再刪除掉。從而實現跨域的請求。

jsonp是一個規則,遠程傳過來時函數包裹着數據

image-20191030093524897

jsonp只能用get,即便你用post,內部也會用get

image-20191030094110020

image-20191030094808713

相關文章
相關標籤/搜索