后臺學習——django(1)

此段內容簡要來自自強學堂的教程
詳情請查詢自強學堂

一、 后臺的運作流程

  1. 接收request請求
  2. 處理數據
  • 獲取請求數據
  • 訪問數據庫
  • 生成返回數據
  1. 返回response回復

二、 安裝django

  1. 前期要求
  • windows8.1系統
  • python 2.7.12
  • pip 8.1.2

(以后的代碼都基于這個來操作,如不同,請自行更改)

  1. 在命令提示符(以后稱為終端)中輸入pip install django(基于django 1.9.7)
  2. 其他系統請查看自強學堂的教程

三、 創建django項目

  1. 新建project,終端進入要創建的項目目錄,輸入

     # project-name為項目名字
     django-admin.py startproject project-name
    
  2. 新建app

     # 注意分清project和app的不同
     cd project-name
     python manage.py startapp app-name
    
  3. 同步數據庫

     python manage.py makemigrations
     python manage.py migrate
    
  4. 創建超級管理員

     # 要記住超級管理員的帳號和密碼呀
     python manage.py createsuperuser
     # 以下是修改密碼的命令
     # python manage.py changepassword username
    
  5. 打開目錄
    # 運行以上代碼后的目錄
    django-admin.py startproject server
    cd server
    python manage.py startapp learning
    python manage.py makemigrations
    python manage.py migrate
    python manage.py createsuperuser

     server
        ├────learning
        |        ├────migrations
        |        |       └──__init__.py
        |        ├────__init__.py
        |        ├────admin.py
        |        ├────apps.py
        |        ├────models.py
        |        ├────tests.py
        |        └────views.py
        ├────server
        |        ├────__init__.py
        |        ├────settings.py
        |        ├────urls.py
        |        └────wsgi.py
        ├────db.sqlite3
        └────manage.py
    
  6. 添加項目到settings

     # 打開`server/server/settings.py`,在里面找到這段代碼
     INSTALLED_APPS = [
         'django.contrib.admin',
         'django.contrib.auth',
         'django.contrib.contenttypes',
         'django.contrib.sessions',
         'django.contrib.messages',
         'django.contrib.staticfiles',
     ]
     # 改為
     INSTALLED_APPS = [
         'django.contrib.admin',
         'django.contrib.auth',
         'django.contrib.contenttypes',
         'django.contrib.sessions',
         'django.contrib.messages',
         'django.contrib.staticfiles',
         'learning',# 新添加的一行
     ]
     # 以后創建項目都要這樣干
    
  7. 測試

  • 在終端輸入python manage.py runserver 127.0.0.1:8000,回車
    這個方法要記住,用來開啟服務器,以后每改一次后臺代碼都要使用
  • 打開瀏覽器在地址欄里填上127.0.0.1:8000localhost:8000,回車
  • 如果瀏覽器顯示這個頁面,就證明成功了

四、 接收請求

好了,講了那么多廢話終于進入正題了,我們開始后臺的第一步——接收請

  1. 首先我們要了解一下客戶端(瀏覽器)和服務端(服務器)之間是怎么交流的
  • 我們平時打開網站,都會在地址欄里輸入網址,當然這可以是簡寫的網址
    像我們可以輸入baidu.com,瀏覽器就會自動地解析成為http://www.baidu.com/,其中http是網絡協議,這個暫時不用管,www.baidu.com是域名,客戶端會訪問該域名所指IP所在的主機,這個也不用管啦。重點是最后的/,沒錯,服務器就接收到這個東西。我們再看一下訪問過程的請求頭:

       # 看到了吧, GET后面就跟著一個'/'
       GET / HTTP/1.1
       Host: www.baidu.com
       Connection: keep-alive
       Cache-Control: max-age=0
       Upgrade-Insecure-Requests: 1
       User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
       Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
       Accept-Encoding: gzip, deflate, sdch, br
       Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2
       Cookie: BAIDUID=43657EBE6AA73B7E1710A565BF7697FE:FG=1; BIDUPSID=43657EBE6AA73B7E1710A565BF7697FE; PSTM=1467522996; shifen[44018713211_80615]=1468034685; BDSFRCVID=eY_sJeC62CUL-TnRAMJvUrrNgT-WknTTH6aIbHc-yy8Uyd3Nd6u1EG0PfvlQpYD-8bNXogKK3gOTH4jP; H_BDCLCKID_SF=fnk8oIPyfbrofbKk2tnhb-_eqxby26n-yGOeaJ5nJDoTSq4z3-TCLfup5RoHbf6MQPjUBbrmQpP-HqTPy--V2Jcb3qrbJM6bJjIDKl0MLnQ-DMjxWf8Ve-DNWMnMBMPe52OnaIb_LIcjqR8Zj6_5jj3P; BD_CK_SAM=1; BD_HOME=0; H_PS_PSSID=20559_1424_17710_20515_13290_20537_20416_17001_15822_11648; BD_UPN=12314553; __bsi=12036617177119872805_00_61_N_N_2_0303_C02F_N_N_Y_0
    
  • 那我們看一下一個完整的URL到底是什么
    http://www.lxweimin.com:80/search?q=python&page=1&type=notes
    http:網絡協議
    www.lxweimin.com:域名
    80:端口
    /search:路徑
    q=python&page=1&type=notes:查詢
    當然,有些URL還有#xxx的,想要仔細了解的請自行google、必應或者百度
    我們再看一下請求頭:

       # GET后面變成了/search?q=python&page=1&type=notes
       GET /search?q=python&page=1&type=notes HTTP/1.1
       Host: www.lxweimin.com
       Connection: keep-alive
       Cache-Control: max-age=0
       Upgrade-Insecure-Requests: 1
       User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
       Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
       Referer: http://www.lxweimin.com/
       Accept-Encoding: gzip, deflate, sdch
       Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2
       Cookie: remember_user_token=W1syNDM2NTI0XSwiJDJhJDEwJENQb1lsdXZWYThHUENOakJpTnVoRnUiLCIxNDY3OTg1NTQ3LjkwNDA0OTIiXQ%3D%3D--c54eb4a79065717f410d814207710a898003f4a9; read_mode=day; default_font=font2; __utmt=1; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1467985058,1467985361,1468031998,1468040600; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1468040628; __utma=194070582.1535447585.1467982131.1468031998.1468040601.4; __utmb=194070582.4.10.1468040601; __utmc=194070582; __utmz=194070582.1468040601.4.3.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmv=194070582.|2=User%20Type=Member=1; _session_id=OWxRN2kyL2txWm9lUVYrTk9aYS9kbmQwM29Xemc3THlmV2R0MnZmYW9PNG9uOGFwWVVXN0JSOGlqUVBXVHJLaEVMbHdpaUV4bkhyOTdXQjNvVjQ5MU05M1JFaERQeDZibk4yV0JtZjh5Z3QrS09GT2ZFczZTd0tyalA3UW9JYzZXRXczSE45a05zRmw3cG02Z2VlTHFSK0pxOFR1MGtDdVhaZmlBMEF1cmkwTDFwSjNud1FrVStSeTNMMC9qek54ZUs4bEpJbHBFajF4dHFoaWdFdHRnd08wWGNGWUdWMXlCeXlwQzVYNEsxZFpGOHEyQjRNVFR1MFhnUUdGTEZCeEQrVS81aXV5QllWeXlxcVNsMXJLU05HZHFBSUlnWUlCQ0kzOXhmU3JraENVZjhnNUMrS1pGN3dYR2RIV0JadnV6S2dwbnRxR2lnMEdIeDEvbVJRZmZQN3JiWWxhME8yd0E3NHJTY2czbmR2dmVlaFBMSjhnNVR3SXZ5V2ZzaVZQdEJDMmJZUnZSYnJvaldKN0pTSVJPc2FwdnRaazkzRjNTbFdwbWlvVUdhTkZybVFnalBnLzNsYUQvblY0SmdaWWdpOWZoNU1DWjhBa0VRMTZKSngyNW5pTk51MlJwRWpyOTZqQ1FiWHlxTjA9LS1GWXRsb0FTa2x4RnpXTnR4Y09OK1BBPT0%3D--e7f6d8ccdf1b2be2d1dbb7c44518f2057ef9c80a
    
  • 通過上面兩個請求頭可以發現,最大的不同就是路徑查詢數據了(我是不會告訴你后面的信息服務器也有用滴,畢竟假象中的你不會后臺),也就是說我們能處理操作的主要就是路徑和查詢數據了,通常而言,我們會根據不同的路徑來返回不同的頁面,根據查詢數據來返回相應的細節
    (注:POST方法的話查詢數據會在請求頭的底部,其實除了這個我也不知道GET和POST到底有什么區別,呵呵)
    伯樂在線:GET和POST有什么區別?及為什么網上多數答案都是錯的

  1. 編寫路由
  • 不同的路徑返回不同的頁面,我們稱之為路由,設置路由就是我們的第一步
    我們看回之前用django創建的目錄里面的文件,應該能猜到吧,就是那個
    urls.py的文件了,我們用編輯器打開看代碼(別告訴我你用記事本!!)
    """server URL Configuration

       The `urlpatterns` list routes URLs to views. For more information please see:
           https://docs.djangoproject.com/en/1.9/topics/http/urls/
       Examples:
       Function views
           1. Add an import:  from my_app import views
           2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
       Class-based views
           1. Add an import:  from other_app.views import Home
           2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
       Including another URLconf
           1. Import the include() function: from django.conf.urls import url, include
           2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
       """
       # 看得懂英文注釋的孩子就看吧,但不要問我這個英語渣
       from django.conf.urls import url
       from django.contrib import admin
    
       urlpatterns = [
           # 這里就是寫路由的地方了
           # url是分配各個路徑往的接口,就像大佬在支配著小弟一般
           # 第一個參數是正則表達式,用來匹配對應的路徑
           # 大家懂正則怎么寫吧,不懂的看后面的連接
           # 第二個參數就是前往的方向了(這個先別管)
           url(r'^admin/', admin.site.urls),# 我知道這不是你寫的
           # 我們先嘗試著創建第一個路由
           url(r'^$')# 這個是我寫的
           # 這個路由匹配路徑為空的路徑,就是我們平時直接輸入域名訪問的路由
           # 雖然這個寫法不正確,但先別管,接著看
           # 注意django匹配路徑的時候已經去掉路徑開頭的'/'了
       ]
    

    給菜鳥看的正則表達式菜鳥教程(有本事打我呀)

  1. 連接到接口
  • 接口就是路由處理好URL后調用的函數,在我看來一個正常的網站的接口就只分成三類,分別是:
    • 頁面接口(返回HTML文件)
    • 靜態文件接口(返回CSS、JS、圖像等靜態文件)
    • 功能接口(主要用來處理數據)
  • 那我們開寫第一個接口吧
    • 打開learning文件夾里面的view.py
      from django.shortcuts import render

        # Create your views here.
      
    • 添加幾行代碼
      # -- coding: utf-8 --
      # 上面這行注釋是要輸進去的,這樣的話解析才可以出現中文,不然會報錯,原因在后面
      from django.shortcuts import render
      # 導入HttpResponse函數,用來輸出信息
      from django.http import HttpResponse

        # Create your views here.
        # 接口用函數定義
        def index(request):
            # 參數request是請求頭對象,很多請求信息都可以通過request來獲取
            # 雖然在這里并沒有什么卵用(摳鼻孔表情.jpg)
            # 無論是什么形式的數據,返回時都要變成字符串
            # 該接口返回一個字符串"學習后臺的第一個接口"
            return HttpResponse(u"學習后臺的第一個接口")
      
    官網解釋# -*- coding: utf-8 -*-
    • 再次打開之前的urls.py,把之前寫的路由改一下
      # -- coding:utf-8 --
      from django.conf.urls import url
      from django.contrib import admin
      # 把之前寫的接口導入進來供路由使用
      from learning import views as learning

        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            # 把index接口接到默認路徑上
            url(r'^$', learning.index),
        ]
      
    • 開啟服務器,再打開網頁localhost:8000

    • 如果看到下面的網頁,證明路由已經開始運作了


  1. 獲取查詢數據
  • 上面是把路由搞定了,但請求數據可不止路徑,還有查詢數據呢
    請求提交查詢的方法主要有兩種,分別是GET和POST(說還有HEAD、OPTIONS、PUT、DELETE和TARCE的一邊去)

  • GET的數據獲取

    • 我們先看回之前URL中的查詢部分

        q=python&page=1&type=notes:查詢
      
    • 請求頭中查詢是由一對對鍵名和鍵值組成,鍵名和鍵值由'='相連,對與對之間用'&'相連,我們要做的就是根據鍵名獲取相對應的鍵值,django處理這種事炒雞方便,直接調用接口參數中request的GET屬性就好。

    • 樣例:文件為之前使用過的接口文件views.pyurls.py
      views.py文件中的代碼
      # -- coding: utf-8 --
      from django.shortcuts import render
      from django.http import HttpResponse

        # Create your views here.
        def index(request):
            return HttpResponse(u"學習后臺的第一個接口")
      
        def query(request):# 新添加的查詢接口
            name = request.GET['name']# 查詢GET方法傳過來的name參數
            time = request.GET['time']# 查詢GET方法傳過來的time參數
            return HttpResponse("Good " + time + ', ' + name + '.')
      

    urls.py文件中的代碼
    # -- coding:utf-8 --
    from django.conf.urls import url
    from django.contrib import admin
    from learning import views as learning

         urlpatterns = [
             url(r'^admin/', admin.site.urls),
             url(r'^$', learning.index),
             url(r'^query', learning.query),# 添加了一個新接口到query
         ]       
    

    重啟服務器,打開網址localhost:8000/query?name=ben&time=morning
    如果你能看到下圖的效果,就證明你已經成功了

    你還可以修改以下name和time的參數試試

  • POST數據獲取

    • POST的數據獲取跟GET差不多(就改了一下屬性),調用接口參數中request的POST屬性就可以了,post的調用我倒是不知道怎么直接用瀏覽器訪問(知道的大神請告訴我,收下我的膝蓋),不過我倒是會一點前端,可以用表單來提交post請求,這時我們就要新建一個文件夾templateslearning文件夾里面,然后在添加一個html文件test.htmltemplates文件夾里面,現在的項目文件如下:

       server
          ├────learning
          |        ├────migrations
          |        |       └──__init__.py
          |        ├────templates
          |        |       └──test.html
          |        ├────__init__.py
          |        ├────admin.py
          |        ├────apps.py
          |        ├────models.py
          |        ├────tests.py
          |        └────views.py
          ├────server
          |        ├────__init__.py
          |        ├────settings.py
          |        ├────urls.py
          |        └────wsgi.py
          ├────db.sqlite3
          └────manage.py
      

      注意以后把所有的網頁文件都放在templates文件夾里面,django會默認在這個文件夾里面查找滴

    • 打開test.html,在里面輸入以下代碼:

       <!doctype html>
       <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <title>test</title>
        </head>
        <body>
            <!--
                這里的action指的是要連接到的路徑
                這里的method指的是請求方法
            -->
            <form action="post" method="post">
                <table border="0" cellspacing="" cellpadding="">
                    <tr>
                        <td>用戶名</td>
                        <td>
                            <!--
                                   name的值主要用于獲取文本框里面的內容
                                   下面的密碼框的name也一樣
                            -->
                            <input type="text" name="username"/>
                        </td>
                    </tr>
                    <tr>
                        <td>密碼</td>
                        <td>
                            <input type="password" name="password"/>
                        </td>
                    </tr>
                    <tr>
                        <td></td>
                        <td>
                            <input type="submit" value="提交" />
                        </td>
                    </tr>
                </table>
            </form>
           </body>
       </html>
      

      你可以雙擊打開網頁看一下,其實就是一個超級簡單登錄頁面,如下圖


    • 修改server/server/urls.py
      # -- coding:utf-8 --
      from django.conf.urls import url
      from django.contrib import admin
      from learning import views as learning

       urlpatterns = [
           url(r'^admin/', admin.site.urls),
           url(r'^$', learning.index),
           url(r'^query', learning.query),
           url(r'^test', learning.test),# 新添加的頁面(頁面接口)
           url(r'^post', learning.post),# 調用post接口獲取信息(功能接口)
       ]
      
    • 修改server/learning/views.py
      # -- coding: utf-8 --
      import sys# 接下來三行是用于處理中文編碼問題
      reload(sys)
      sys.setdefaultencoding('utf-8')
      from django.shortcuts import render
      from django.http import HttpResponse

       # Create your views here.
       def index(request):
           return HttpResponse(u"學習后臺的第一個接口")
      
       def query(request):
           name = request.GET['name']
           time = request.GET['time']
           return HttpResponse("Good " + time + ', ' + name + '.')
      
       # 新添加的頁面接口函數,用于返回test.html頁面
       # render函數會自動在templates文件夾里面查找頁面
       # 這也是之前要把網頁文件放在templates文件夾里面的原因
       def test(request):
           return render(request, 'test.html')
      
       # 功能接口:調用request.POST[name]獲取數據
       def post(request):
           username = request.POST['username']# 這是之前設置name屬性原因
           password = request.POST['password']# 同意樓上,+1
           response = '你輸入的用戶名為' + username + '<br />'
           response += '你輸入的密碼為' + password + '<br />'
           return HttpResponse(response)
      
    • 打開網頁localhost:8000/test,輸入用戶名和密碼。好了,當你滿懷期待滴按下提交按鈕的時候,看到了返回的結果,又到了一臉懵的時候了

      (終于給我用上了第一張表情圖了)

      好了,不逗你們了,原因其實是因為防止CSRF攻擊,可以看一下這個CSRF百度百科,其實也就是django防止黑客攻擊采取的一種防護措施,具體原理說了你也不懂(其實我也不懂,尷尬臉.jpg),不管怎樣,總不能所有表單提交都不可以吧,其實解決方法有兩種:

      • 如果你覺得你的網站是不會有黑客來攻擊,或者你的網站是沒用滴,就算黑客來了還可以熱情滴打個招呼,“嘿,你好黑客,可以教我黑客么”的話可以這樣干
        打開server/server/settings.py
        找到'django.middleware.csrf.CsrfViewMiddleware',,然后注釋掉(干掉他)

          MIDDLEWARE_CLASSES = [
              'django.middleware.security.SecurityMiddleware',
              'django.contrib.sessions.middleware.SessionMiddleware',
              'django.middleware.common.CommonMiddleware',
          #   'django.middleware.csrf.CsrfViewMiddleware', 沒錯就是這一句
              'django.contrib.auth.middleware.AuthenticationMiddleware',
              'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
              'django.contrib.messages.middleware.MessageMiddleware',
              'django.middleware.clickjacking.XFrameOptionsMiddleware',
          ]
        
      • 如果你真的想要實現django的防止CSRF模式攻擊功能的話,那就要一番大改動了

        • 修改server/learning/templates/test.html

           <!doctype html>
           <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>test</title>
            </head>
            <body>
                <form action="post" method="post">
                    {% csrf_token %}
                    <!--在form表單中添加{% csrf_token %}-->
                    <table border="0" cellspacing="" cellpadding="">
                        <tr>
                            <td>用戶名</td>
                            <td>
                                <input type="text" name="username"/>
                            </td>
                        </tr>
                        <tr>
                            <td>密碼</td>
                            <td>
                                <input type="password" name="password"/>
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td>    
                                <input type="submit" value="提交" />
                            </td>
                        </tr>
                    </table>
                </form>
               </body>
           </html>
          
        • 修改server/learning/views.py
          # -- coding:utf-8 --
          import sys
          reload(sys)
          sys.setdefaultencoding('utf-8')
          from django.shortcuts import render
          from django.http import HttpResponse
          # 導入csrf_protect
          from django.views.decorators.csrf import csrf_protect

            # Create your views here.
            def index(request):
                return HttpResponse(u"學習后臺的第一個接口")
          
            def query(request):
                name = request.GET['name']
                time = request.GET['time']
                return HttpResponse("Good " + time + ', ' + name + '.')
          
            def test(request):
                return render(request, 'test.html')
          
            # 引用@csrf_protect
            @csrf_protect
            def post(request):
                username = request.POST['username']
                password = request.POST['password']
                response = '你輸入的用戶名為' + username + '<br />'
                response += '你輸入的密碼為' + password + '<br />'
                return HttpResponse(response)
          
        • 好吧,修改的地方也不多,記住form表單里面要加上{% csrf_token %}views.py里面要導入csrf_protect,并在表單提交后的方法前加入@csrf_protect就可以了,是不是很簡單

  1. 接收更多的請求
  • 實際應用當中要獲取的請求信息肯定不可能單單只有這么點,比如要獲取請求方法來用不同的方法處理數據,比如要獲取客戶端的IP地址、cookie等來做防爬蟲處理,比如獲取路徑做更多的動態處理,如果你要用到這些或者更多的話,可以自行google、必應或者百度,懶的話可以看這個:request對象與response對象的各種屬性

(注:鑒于以后的代碼越來越長,占據的篇幅越來越多,以后代碼只顯示需要修改的部分,你們請自行修改代碼,不要復制粘貼了,認真臉.jpg,當然,如果是大改的話還是會全部展示出來的)

五、 處理數據

獲取到請求數據,怎么用就看你的啦,可沒有人限制你哦,但不管你怎么處理,在很多地方都是具有共性的,如大部分都需要經過訪問數據庫的步驟,知道這個對以后做任何項目都會很有用。為了更好滴說明問題,我將以一個簡單的登錄注冊的系統作為介紹這些方法的載體。

  1. 構建思維導圖
  • 做一個項目,首要的第一步就是理清整個網站的邏輯,只有邏輯清晰了,后面的工作都會很順利,而理清邏輯的方法有很多,我推薦一種——思維導圖,登錄注冊系統的邏輯如下:


  • 這個是我用百度腦圖做的一個思維導圖,大家也可以使用其他制作思維導圖的工具
  1. 前期準備
  • 你問什么是前期準備?當然是之前那些接收請求的步驟啦。

  • 準備html文件index.html,添加到templates目錄里(test.html可以刪掉了),代碼如下:
    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <title>登錄注冊系統</title>
    </head>
    <body>
    <div>
    <form action="login_register" method="post">
    {% csrf_token %}
    <table>
    <tr>
    <th>帳號:</th>
    <td><input type="text" id="username" name="username" maxlength="20"/></td>
    </tr>
    <tr>
    <th>密碼:</th>
    <td><input type="password" id="password" name="password" maxlength="20"/></td>
    </tr>
    <tr>
    <th></th>
    <td>
    <label>
    <input type="radio" name="way" value="login" checked="checked"/>登錄
    </label>
    <label>
    <input type="radio" name="way" value="register"/>注冊
    </label>
    </td>
    </tr>
    <tr>
    <th></th>
    <td><input type="submit" id="submit" value="提交" onclick="return check()"/></td>
    </tr>
    </table>
    </form>
    </div>
    <script type="text/javascript">
    function check(){
    var username = document.getElementById('username');
    var password = document.getElementById('password');
    if(username.value == ''){
    alert('帳號不能為空,請重新輸入');
    username.select();
    }else if(password.value == ''){
    alert('密碼不能為空,請重新輸入');
    password.select();
    }else{
    return true;
    }
    return false;
    }
    </script>
    </body>
    </html>
    直接雙擊打開可以看到下圖:

    解析一下html的作用,html提供一個表單給用戶輸入帳號和密碼以及選擇登錄還是注冊,文本框限制輸入20個字符,提交按鈕點擊后會先驗證是否為空,然后以post的方法提交到login_register上。
    此時目錄結構如下:

        server
           ├────learning
           |        ├────migrations
           |        |       └──__init__.py
           |        ├────templates
           |        |       └──index.html
           |        ├────__init__.py
           |        ├────admin.py
           |        ├────apps.py
           |        ├────models.py
           |        ├────tests.py
           |        └────views.py
           ├────server
           |        ├────__init__.py
           |        ├────settings.py
           |        ├────urls.py
           |        └────wsgi.py
           ├────db.sqlite3
           └────manage.py
    
  • 修改server/server/urls.py文件,大改如下:
    # -- coding:utf-8 --
    from django.conf.urls import url
    from django.contrib import admin
    from learning import views as learning

       urlpatterns = [
           url(r'^admin/', admin.site.urls),
           url(r'^$', learning.index),# 首頁
           url(r'^login_register', learning.login_register),# 登錄注冊接口
       ]
    
  1. 接口實現
  • 好了,做好一切前期準備,我們要開始編寫接口文件server/learning/views.py了,在urls.py文件里面就可以看出我們要寫兩個接口函數了,準備好基本的代碼
    # -- coding:utf-8 --
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    from django.shortcuts import render
    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_protect

       def index(request):
           pass
    
       def login_register(request):
           pass
    
  • 萬事都要從簡單的開始,我們先挑頁面接口來弄:

       def index(request):
           return render(request, 'index.html')
    

    So easy!

  • 接下來就是實現login_register接口了,因為這個函數包含了兩個功能,遵循一個函數解決一個功能的原則,我們可以把它拆分為login接口和register接口:
    def login_register(request):
    username = request.POST['username']
    password = request.POST['password']
    way = request.POST['way']
    if way == 'login':
    return HttpResponse(login(username, password))
    elif way == 'register':
    return HttpResponse(register(username, password))

       def login(username, password):
           pass
    
       def register(username, password):
           pass
    
  • 接下來我們就卡住了,原因是不知道怎么訪問數據庫,其實django為數據庫做了大量的處理,我們可以很方便滴進行數據庫交互。

    • 第一步當然是建表啦,django通過設置類來快速建表,打開server/learning/models.py,修改代碼如下:
      from future import unicode_literals

        from django.db import models
      
        # Create your models here.
        # 新建一個類叫user,其實就是新建一張叫user的表
        class user(models.Model):
            username = models.CharField(max_length = 20)
            password = models.CharField(max_length = 20)
            # 此函數是為了用該名字來顯示對象
            def __unicode__(self):
                return self.username
      

      我們可以看到數據庫類有兩個字段,分別是usernamepassword,其實django還會默認添加一個id字段

    • 然后同步數據庫,在終端輸入如下代碼(記住每次更改數據庫,改寫models.py文件,都需要同步數據庫)

        python manage.py makemigrations
        python manage.py migrate
      

      同步的同時,django會自動為你生成數據庫和表,再也不用那么麻煩去建表了

    • 為了在可視化數據庫中看到此表,還需要在server/learning/admin.py中添加一點
      from django.contrib import admin
      from learning.models import user# 導入user類

        # Register your models here.
        admin.site.register(user)# 把user添加到admin
      
    • 數據庫和表創建了,那我們應該怎么使用數據庫呢,數據庫的基本操作有插入、查詢、更改、刪除,django都為其提供了方法,這里只講述插入與查詢,當然每次對數據庫操作都需要把其導入進來

        from learning.models import user
      
      • 插入
        假設我們要插入一條username='ben'password='ben'的記錄(因為默認是非空的字段,所以要將所有字段都要填入,當然,默認的自增id除外),我們可以這樣干

          user(username='ben', password='ben').save()
          #等同于SQL語句:INSERT INTO user(username,password) values ('ben','ben')
        
      • 查詢
        假設我們要獲取所有數據,則使用下面的語句:
        alldata = user.objects.all()
        #等同于SQL語句:SELECT * FROM user
        假設我們要通過一個字段來獲取數據(具有唯一性),則使用下面的語句:

          onedata = user.objects.get(username='ben')
          #約等同于SQL語句:SELECT * FROM userWHERE username='ben'
        

        假設我們要通過過濾器來找多條數據,則使用下面的語句:

          datas = user.objects.filter(password__in=['ben','sam','jack'])
          #約等同于SQL語句:SELECT * FROM userWHERE username in ('ben','sam','jack')
        
    • 知道數據庫怎么操作之后就可以很容易寫剩下來的兩個函數了,我們返回server/learning/views.py
      def login(username, password):
      try:
      person = user.objects.get(username=username)
      try:
      person = user.objects.get(username=username,password=password)
      return '登錄成功'
      except:
      return '登錄密碼錯誤'
      except:
      return '不存在該用戶'

          def register(username, password):
              try:
                  person = user.objects.get(username=username)
                  return '注冊帳號已存在'
              except:
                  user(username=username,password=password).save()
                  return '注冊成功'
      

      注意在使用user.objects.get()方法時,無論找到的數據是多于一條還是一條都沒有,都會報錯

  1. 測試
  • 一個項目的完成總免不了對其的測試,畢竟在程序員的眼里,用戶是這樣使用他們開發的軟件的:


    呵呵,誰讓你是個程序猿呢,唉,為了保證程序的正確運行,還是要進行必要的測試的

  • 頁面接口測試
    • 網址localhost:8000測試如下圖
  • 基本測試
    • 帳號文本框為空提交


    • 密碼文本框為空提交


    • 帳號和密碼文本框均不能輸入大于20個字符的值
  • 注冊測試
    • 不存在同名用戶時


    • 存在同名用戶時


  • 登錄測試
    • 帳號密碼均正確時


    • 密碼錯誤時


    • 帳號不存在時


  1. 總結
  • 好了,程序完美滴通過了測試,證明我們之前學到的東西并沒有白費,處理數據KO

六、 返回響應數據

  1. 用于相應的數據基本有三種,跟接口類別相對應,分別是:
  • html文件
  • 普通文本
  • 靜態文件
  1. 其實在之前我已經在默默滴滲透了返回html文件和普通文本的方法:

     # 返回放在templates文件夾里面的html文件
     return render(request, 'index.html')
     # 返回普通文本
     return HttpResponse('Hello, world!')
    
  2. 好像就剩下靜態文件沒有講了,但是靜態文件又是什么?

  • 靜態文件就是像CSS、JavaScript、圖片等一類不會因為請求的不同而不同的文件(相對應的是html文件,同一個網頁是可以呈現不同的內容的)
  • 靜態文件統一放在app中的static文件夾里面
  • 靜態文件的引用
    • 在所有要引用的連接前加上{% load staticfiles %}
    • 添加引用的文件連接到相對應的地方上,如<img src="{% static "images/hi.jpg" %}" />
  1. 假設我們要為之前的index.html添加樣式,引用外鏈CSS文件index.css
  • 創建新文件index.cssserver/learning/static/css文件夾中(要自己新創建文件夾),其代碼如下:
    table{
    width: 300px;
    margin:0px auto;
    }

  • 修改server/server/urls.py文件(主要是在底部添加以下代碼)
    from django.conf.urls.static import static
    from django.conf import settings

       urlpatterns+=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
    
  • 修改server/learning/templates/index.html文件(在head標簽中的底部添加代碼)
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href='{% static "css/index.css" %}' />

  • 查看成果:


    表單成功居中

七、 后言

  • django提供了大量的API和很多方便的使用方法,但是django有很多方法都嚴重影響到前端,雖然如果按著這樣來編寫的話,可以很方便構建網站,但過于耦合會使頁面不具有適應性,也就是說如果把前端文件安置到其他后臺里面會適用不了,只能在django后臺使用,而且不能實現前端和后臺分離。在之后的學習過程中,我都會盡可能滴讓后臺不影響到前端。

下期文章:后臺學習——django(2)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容