01:django基礎篇

Django其餘篇

目錄:

1.1 django初探     返回頂部

  一、django、tornado、flask比較html

      Django: 1個重武器,包含了web開發中經常使用的功能、組件的框架;(ORM、Session、Form、Admin、分頁、中間件、信號、緩存、ContenType....);python

      Tornado: 最大特性就是異步非阻塞、原生支持WebSocket協議;jquery

      Flask:封裝功能不及Django完善,性能不及Tornado,可是Flask的第三方開源組件比豐富;web

      使用參考ajax

        1. 小型web應用設計的功能點很少使用Flask;
        2. 大型web應用設計的功能點比較多使用的組件也會比較多,使用Django(自帶功能多不用去找插件);
        3. 若是追求性能能夠考慮Tornado;sql

  二、MVC和MVT比較數據庫

    MVC       Model(數據庫 )        View(模板文件)       Controller(業務處理)django

        M( Model):  主要封裝對數據庫層的訪問,對數據庫中的數據進行增、刪、改、查操做。
        V( View):  用於封裝結果,生成頁面展現的html內容。
        C(Controller):  用於接收請求,處理業務邏輯,與Model和View交互,返回結果。json

    MTV       Model(數據庫)        Template(模板文件)        View( 業務處理)flask

        M( Model):  與MVC中的M功能相同,負責和數據庫交互,進行數據處理。
        V( View):  與MVC中的C功能相同,接收請求,進行業務處理,返回應答。
        T(Template):  與MVC中的V功能相同,負責封裝構造要返回的html。

1.2 第一個django項目     返回頂部

  一、安裝django

       pip3 install django==2.0.4

  二、建立django項目

C:\Users\tom>    d:                          # 進入d盤
D:\>    django-admin startproject mysite     # 建立django項目(能夠看到c盤生成了mysite文件夾的django項目)
D:\>    cd mysite                            # 進入項目目錄
D:\mysite>    python manage.py runserver 127.0.0.1:8000       # 運行mysite項目
# 瀏覽器訪問:http://127.0.0.1:8000/

  三、建立子應用

      c:\mysite>python manage.py startapp app01

  四、django項目和子應用各文件做用

C:.
│  db.sqlite3               # sqlite數據庫文件(settings.py中默認鏈接的數據庫)
│  manage.py              # 項目管理腳本
│
├─app01 (子應用目錄)
│  │  admin.py            # 配置django admin後臺
│  │  apps.py
│  │  models.py            # 配置django表,負責和數據庫交互,進行數據處理
│  │  tests.py
│  │  views.py             # 接收請求,進行業務處理,返回應答
│  │  __init__.py
│  │
│  └─migrations
│          __init__.py
│
└─mysite
    │  settings.py           # 項目配置文件
    │  urls.py              # 總路由
    │  wsgi.py
    │  __init__.py
django項目文件註釋

  五、settings.py基本配置

      1)配置模板的路徑(在項目根路徑下建立文件夾  D:\mysite\templates

TEMPLATES = [
    {
       'DIRS': [os.path.join(BASE_DIR,'templates')],
    },
]
TEMPLATE_DIRS = (os.path.join(BASE_DIR,  'templates'),)

      2)配置靜態目錄(在項目根路徑下建立文件夾 D:\mysite\static

#像ccs和js這些靜態文件若是想要使用必須在這裏配置路徑
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

      3)註釋CSRF(若是以post方式提交請求能夠先註釋這裏進行測試)

MIDDLEWARE = [
    # 'django.middleware.csrf.CsrfViewMiddleware',
]

      4) 修改settings.py中時區

#### 一、Django默認配置是:
TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'en-us'

#### 二、Django1.9之前應設置爲:
TIME_ZONE = 'Asia/Shanghai'
LANGUAGE_CODE = 'zh-cn'

####三、Django1.9之後至目前的2.1,應設置爲:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

1.3 django render/redirect/HttpResponse 和 request.GET request.POST     返回頂部

  一、render/redirect/HttpResponse 函數用法

      render  :  返回html頁面

      redirect  :  重定向到新的頁面

      HttpResponse  :  返回字符串(通常爲json字符串)

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]
urls.py
from django.shortcuts import render,redirect,HttpResponse
import json

def index(request):
    return render(request, 'index.html', {'users':['zhangsan','lisi','wangwu']})
    # return redirect('https://www.baidu.com')
    # return HttpResponse(json.dumps({"name":"zhangsan"}))
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h1>我是首頁</h1>
    {{ users }}
</body>
</html>
index.html

  二、模板使用

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]
urls.py
from django.shortcuts import render,redirect,HttpResponse

def index(request):
    return render(request, 'index.html',
                  {
                      'users':['zhangsan','lisi','wangwu'],
                      'data':{"name":"zhangsan","age":100,"sex":"人妖"},
                      'num': 12,
                   })
views.py
<body>
    <h1>一、users: 循環列表</h1>
    {% for u in users %}
        <p>{{ u }}</p>
    {% endfor %}

    <h1>二、data:循環字典</h1>
    {% for k,v in data.items %}
        <p>{{ k }} -- {{ v }}</p>
    {% endfor %}

    <h1>三、if判斷</h1>
    {% if num > 16 %}
      <a>num大於16</a>
   {% else %}
      <a>num小於16</a>
   {% endif %}
</body>
index.html

1.4 Django各類url寫法     返回頂部

  一、無正則匹配url  (http://127.0.0.1:8000/index/?nid=1&pid=2)

  二、基於(\d+)正則的url

  三、基於正則分組(?P<nid>\d+),能夠不考慮接收參數順序 (推薦)

  四、使用name構建本身想要的url

  五、Django路由分發    並使用name構建url路徑

  re_path(r'app01/',include(('app01.urls','app01'),namespace='app01'))

from django.contrib import admin
from django.urls import path, re_path,include
from app01 import views


urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'index1/$', views.index1, name='indexname1'),          # 方法1:無正則匹配url
    re_path('index2/(\d+)/$', views.index2, name='indexname2'),     # 方法2:基於(\d+)正則的url
    re_path('index3/(?P<nid>\d+)/(?P<pid>\d+)/$', views.index3, name='indexname3'),        # 方法3:基於(\d+)正則的url
    re_path('index4/$', views.index4),                               # 方法4:使用name構建本身想要的url
    path('app01/', include('app01.urls', namespace='app01')),       # 方法5:Django路由分發
]
mysite/urls.py
from django.shortcuts import render,redirect,HttpResponse
import json
from django.urls import reverse


# 方法1:無正則匹配url( http://127.0.0.1:8000/index1/?uid=1 )
def index1(request):
    print( request.GET )             # {"uid": "1"}
    nid = request.GET.get('uid')    # 1
    return HttpResponse('無正則匹配url')


# 方法2:基於(\d+)正則的url(  http://127.0.0.1:8000/index2/1/  )
def index2(request, uid):
    print( uid )                    # 1
    return HttpResponse('基於(\d+)正則的url')


# 方法3:基於正則分組(?P<nid>\d+)(  http://127.0.0.1:8000/index3/1/2/  )
def index3(request, nid, pid):
    print(nid)                     # 1
    print(pid)                     # 2
    return HttpResponse('基於正則分組url')


# 方法4:使用name構建本身想要的url (http://127.0.0.1:8000/index4/)
def index4(request):
    url1 = reverse('indexname1')                                    # /index1/
    url2 = reverse('indexname2', args=(1,))                         # /index2/1/2/
    url3 = reverse('indexname3', kwargs={'pid': 1, "nid":2})       # /index3/1/2/
    return render(request, 'index.html')


# 方法5:Django路由分發 (http://127.0.0.1:8000/app01/aaa/)
def aaa(request):
    return HttpResponse('aaa')
app01/views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <p><a href="{% url 'indexname1' %}">  無正則匹配: http://127.0.0.1:8000/index/  </a></p>
    <p><a href="{% url 'indexname2' 1  %}"> 基於(\d+)正在匹配: http://127.0.0.1:8000/index2/1/  </a></p>
    <p><a href="{% url 'indexname3' 1 2 %}">  基於正則分組url: http://127.0.0.1:8000/index3/1/2/  </a></p>
</body>
</html>
index.html
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from django.urls import path,re_path
app_name='app01'
from app01 import views


urlpatterns = [
    re_path(r'aaa/$', views.aaa, name='aaa'),
]
app01/urls.py

1.5 Django的CBV和FBV     返回頂部

  一、FBVfunction  base  view:views.py文件中使用函數

def aaa(request):
    return HttpResponse('aaa')
FBV寫法

  二、CBV(class  base  view):在views.py文件中使用類

      一、 dispatch是父類中用來反射的函數,找對應的函數(比對應函數先執行)

      二、 好比你發送post請求就能夠經過dispatch找到對應的post函數進行處理,get就會找到get函數處理

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from django.urls import path,re_path
app_name='app01'
from app01 import views


urlpatterns = [
    re_path(r'home/$', views.Home.as_view(), name='home'),
]
urls.py
from django.views import View
class Home(View):
    '''使用CBV時必需要繼承view父類'''
    def dispatch(self, request, *args, **kwargs):
        # 調用父類中的dispatch
        result = super(Home,self).dispatch(request, *args, **kwargs)
        # 使用result主動繼承view父類,而後return就能夠重寫父類的dispath方法
        return result

    # 在這裏使用get發來請求就會調用get方法,使用post發來請求就會調用post方法
    def get(self,request):
        print(request.method)
        return HttpResponse('get')

    def post(self,request):
        print(request.method,'POST')
        return HttpResponse('post')
app01/views.py

1.6 先後端交互:提交數據     返回頂部

  一、獲取請求數據

# 一、request.POST
# 二、request.GET
# 三、request.FILES
# 四、request.getlist
# 五、request.method
# 六、request.path_info                   #獲取當前url

  二、舉例

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    re_path(r'login/$', views.login, name='login'),
]
urls.py
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    elif request.method == 'POST':
        post_data = request.POST                      # {"user": "naiqiang.xiao", "gender": "1", "favor": "33", "city": "bj"}
        mul_list = request.POST.getlist('favor')     # ['11', '22', '33']
        return render(request, 'login.html')
app01/views.py
    <form action="/login/" method="post" enctype="multipart/form-data">
        <p>
            <span>input提交:</span>
            <input type="text" name="user" placeholder="用戶名">
        </p>

        {# 一、單選框,返回單條數據的列表 #}
        <p>
            <span>性別: </span>
            男:<input type="radio" name="gender" value="1">
            女:<input type="radio" name="gender" value="2">
        </p>

        {# 二、多選框、返回多條數據列表 #}
        <p>
            <span>愛好: </span>
            籃球:<input type="checkbox" name="favor" value="11">
            排球:<input type="checkbox" name="favor" value="22">
            足球:<input type="checkbox" name="favor" value="33">
        </p>

        {# 三、多選,返回多條數據的列表 #}
        <p>
            <span>地址: </span>
            <select name="city">
                <option value="bj">北京</option>
                <option value="sh">上海</option>
                <option value="gz">廣州</option>
            </select>
        </p>
        <input type="submit" value="提交">
    </form>
login.html

  三、form表單中三個參數做用

''' action="/login/" method="post" enctype="multipart/form-data"  '''
# 一、action="/login/"      # form表單數據提交的路徑
# 二、method="post"         # 以什麼方式提交form表單
# 三、enctype="multipart/form-data"      # 若是須要提交文件須要這個標註

1.7 上傳圖片&預覽功能     返回頂部

  一、使用from表單上傳圖片 及 預覽功能

      1) enctype就是encodetype就是編碼類型的意思。
      2) 默認狀況下,enctype的值是application/x-www-form-urlencoded,不能用於文件上傳。
      3) multipart/form-data是指定將文件以二進制的形式上傳,這樣能夠實現多種類型的文件上傳。

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'upload/',views.upload),
]
urls.py
from django.shortcuts import render
import os

def upload(request):
    if request.method == 'GET':
        return render(request, 'upload.html')

    elif request.method == 'POST':
        obj = request.FILES.get('filename')  # 獲取上傳圖片對象
        file_path = os.path.join('static','images', obj.name)  # static\images\aa.jpg
        f = open(file_path, mode='wb')
        for i in obj.chunks():
            f.write(i)
        f.close()
        imgpath = os.path.join('images',obj.name)  # images\aa.jpg
        return render(request, 'upload.html',{'imgpath': imgpath})
app01/views.py
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <form action="/upload/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p><input type="file" name="filename"></p>
        <input type="submit" value="提交">
    </form>
        <p>圖片預覽</p>
        <p><img src="{% static imgpath %}"></p>
</body>
</html>
upload.html

  二、使用jquery ajax上傳圖片

    1)JQuery AJAX說明

        一、jQuery其實就是一個JavaScript的類庫,其將複雜的功能作了上層封裝,使得開發者能夠在其基礎上寫更少的代碼實現更多的功能

        二、jQuery Ajax本質 XMLHttpRequest 或 ActiveXObject

    2) FormData對象

        一、FormData對象用以將數據編譯成鍵值對,以便用XMLHttpRequest來發送數據。

        二、 其主要用於發送表單數據,但亦可用於發送帶鍵數據(keyed data),而獨立於表單使用。

        三、比起普通的ajax,使用FormData的最大優勢就是咱們能夠異步上傳一個二進制文件。

    3)contentType:(默認: "application/x-www-form-urlencoded")

        一、發送信息至服務器時內容編碼類型(false標識不要對提交的數據)。

        二、若是你明確地傳遞了一個content-type給 $.ajax() 那麼他一定會發送給服務器(即便沒有數據要發送)

        三、設置false做用:告訴JQuery不要設置內容格式

    4)processData(默認: true)

        一、默認狀況下,經過data選項傳遞進來的數據,都會處理轉化成一個查詢字符串

        二、若是要發送 DOM 樹信息或其它不但願轉換的信息,請設置爲 false。

        三、設置false做用:告訴JQuery不要特殊處理這個數據

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'ajax/$',views.ajax_upload),
]
urls.py
from django.shortcuts import render,HttpResponse
import os
import json


def ajax_upload(request):
    if request.method == 'GET':
        return render(request, 'ajaxupload.html')
    elif request.method == 'POST':
        obj = request.FILES.get('fafafa')
        username = request.POST.get('username')  # root
        file_path = os.path.join('static','images', obj.name)  # static\images\aa.jpg
        with open(file_path,'wb') as f:
            for item in obj.chunks():
                f.write(item)
        ret = {'code':True,'data':'sucess'}
        return HttpResponse(json.dumps(ret))
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <div>
        <input type="file" id="fafafa" name="afafaf">
        <a class="upload">上傳</a>
    </div>
    <input type="button" value="提交jQuery" onclick="fqSubmit();">

    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function fqSubmit(){
            var file_obj = document.getElementById('fafafa').files[0];

            var fd = new FormData();            // FormData對象能夠傳字符串,也能夠傳文件對象
            fd.append('username','root');
            fd.append('fafafa',file_obj);
            var xhr = new XMLHttpRequest();

            $.ajax({
                url:'/ajax/',
                type:'POST',
                data:fd,
                //jquery Ajax上傳文件必須指定processData,contentType參數
                processData:false,              //告訴JQuery不要特殊處理這個數據
                contentType:false,              //告訴JQuery不要設置內容格式
                success:function(arg){
                    console.log(111,arg);       //後臺返回的數據  {"code": true, "data": "sucess"}
                }
            })
        }
    </script>
</body>
</html>
ajaxupload.html

1.8 ajax登陸 & 一些經常使用dom 和 jquery操做     返回頂部

  一、ajax登陸

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'login/', views.login, name='login'),
]
urls.py
from django.shortcuts import render,HttpResponse
import os
import json


def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    elif request.method == 'POST':
        print(request.POST)
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username, password)
        if username == 'tom' and password == '123456':
            return HttpResponse(json.dumps({'status':True}))
        else:
            return HttpResponse(json.dumps({'status':False}))
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h2>登陸</h2>
    <div style="">
        <p>
            <input name="username" id="username">
        </p>
        <p>
            <input name="password" type="password" id="password">
        </p>
        <p>
            <input type="button" value="提交" onclick="ajaxSubmit()">
        </p>
        <p id="err-msg" style="color: red;"></p>
    </div>

    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function ajaxSubmit() {
            var username = document.getElementById('username').value;
            var password = document.getElementById('password').value;
            $.ajax({
                url: '/login/',  // 提交url
                data: {'username':username, 'password':password},  // 提交數據
                type: 'POST',  // 提交方式
                dataType: 'JSON',  // 將數據裝換成json格式提交
                traditional: true,  // tradtional爲true阻止深度序列化
                success: function (data) {
                    if(data.status == true){
                        alert('登陸成功')
                        document.getElementById('err-msg').innerText = ''
                        location.href='http://www.baidu.com'
                    }else {
                        console.log('在頁面顯示錯誤信息')
                        document.getElementById('err-msg').innerText = '用戶名或密碼錯誤'
                    }
                }
            })
        }
    </script>
</body>
</html>
login.html

  二、先後端交互必學知識點

      1.  Dom操做   :   http://www.javashuo.com/article/p-xxhoxhih-cg.html

      2.  jquery使用整理  :  http://www.javashuo.com/article/p-mandouxc-cq.html

      3.  ajax最全整理  :  http://www.javashuo.com/article/p-nozltshg-cw.html 

  三、make_password & check_password

from django.contrib.auth.hashers import make_password, check_password

hkey = make_password("123456")  # pbkdf2_sha25615000MAjic...
ret = check_password("123456","pbkdf2_sha25615000MAjic...")  # True
相關文章
相關標籤/搜索