Django後續

環境準備

建立一個Django項目,可使用前面使用命令行建立,在這裏我是使用pycharm建立的。css

記得選擇左邊的Django,Location建立項目的目錄最後一級爲項目的名稱。在這裏咱們能夠建立一個app,如上如我建立了app01。html

建立好後咱們能夠看見一個目錄爲:python

咱們須要在這個目錄的manager.py同級目錄建立一個static的靜態目錄,用來放置css,和js。mysql

再日後咱們須要在setting.py的配置文件作如下配置:正則表達式

  • 找到 'django.middleware.csrf.CsrfViewMiddleware'並把它註釋掉
  • 找到TEMPLATES部分,若是沒有以下代碼,則須要添加:'DIRS': [os.path.join(BASE_DIR, 'templates')]
  • 在文件的最後添加靜態文件目錄,這裏須要注意這裏面是一個元組,因此注意要有逗號(,)。

到這裏咱們的一些基本的配置就配好了。最後咱們獲得的目錄爲sql

上面就是咱們開始Django項目前的一些環境準備。數據庫

 

下面是一個簡單的登陸驗證的頁面

大體能夠寫以下3步:django

  • 在myobj下的urls.py裏面寫下相應的路有關係
  • 在app01目錄下面咱們寫相關的業務代碼,也就是寫相應的視圖函數
  • 在寫相應的html

上面在咱們寫相應的路由關係的時候,咱們須要把把路由關係和視圖函數聯繫起來session

寫法如圖:加上紅色的那一句oracle

第一步就是寫相關的路由關係

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

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index),
]

 

寫好後咱們在寫對應的視圖函數、視圖函數在app01下面的views裏面寫代碼以下

from django.shortcuts import render,redirect
# Create your views here.
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
       if user == 'admin' and pwd == 'admin':
            return redirect('/index/')
        else:
            return render(request,'login.html')
    else:
        return render(request,'login.html')

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

 

 在接下來寫index和login相關的代碼

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="post" enctype="multipart/form-data">
        <p><input type="text" name="user" placeholder="請輸入用戶名"/></p>
        <p><input type="password" name="pwd" placeholder="請輸入密碼"/></p>
        <p><input type="submit" value="登錄"></p>
    </form>
    </div>
</body>
</html>

 

index.html代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>登錄成功</div>
</body>
</html>

 

 記住上面的這些HTML代碼都是放在templates目錄下面的。而static目錄裏面放的是一些js和css文件

上面咱們能夠看到

這個就是登陸界面,當咱們輸入的用戶名和密碼正確的時候就會跳轉到咱們成功的頁面,當咱們失敗的時候還會停留在這個頁面。

 

獲取數據和文件上傳

在視圖裏面(/app01/views.py)
    1、獲取用戶請求數據
        request.GET.get(標籤裏面的name屬性值)   
        request.POST.get(標籤裏面的name屬性值)
        request.FILES.get(標籤裏面的name屬性值)
        PS:
            GET:獲取數據                
            POST:獲取用戶提交數據
            
    2、獲取checkbox等多選的內容
        request.POST.getlist(標籤裏面的name屬性值)
    3 、上傳文件
          # 上傳文件,form標籤作特殊設置
        obj = request.FILES.get('fafafa')
        obj.name
        f = open(obj.name, mode='wb')
        for item in obj.chunks():
            f.write(item)
        f.close()

 

上面使用標籤裏面的name屬性值獲取到的是標籤裏面value屬性值。

關於獲取checkbox等多選的內容實驗

視圖裏面的代碼(/app01/views.py)

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import os
# Create your views here.
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        gender = request.POST.get('gender')
        favor = request.POST.getlist('favor')
        city = request.POST.getlist('city')
        print(user,pwd,gender,favor,city)
        obj = request.FILES.get('upload')
        print(obj,type(obj),obj.name)
        file_path = os.path.join('upload_dir',obj.name)
        with open(file_path, 'wb') as f:
            for i in obj.chunks():
                f.write(i)
        return HttpResponse('ok')
# 打印的結果
#admin admin 1 ['1', '2', '3'] ['sh', 'bj', 'tj']
#2018-07-04日22:00 巡檢記錄.txt <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> 2018-07-04日22:00 巡檢記錄.txt

 

login.html代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login/" method="post" enctype="multipart/form-data">
    <p>
        <input type="text" name="user" placeholder="用戶名">
    </p>
    <p>
        <input type="password" name="pwd" placeholder="密碼">
    </p>
    <p>
        男:<input type="radio" name="gender" value="1">
        女:<input type="radio"  name="gender" value="2">
    </p>
    <p>
        乒乓球:<input type="checkbox" name = "favor" value="1">
        籃球:<input type="checkbox" name = "favor" value="2">
        羽毛球:<input type="checkbox" name = "favor" value="3">
    </p>
    <p>
        <select name="city" multiple>
            <option value="sh">上海</option>
            <option value="bj">北京</option>
            <option value="tj">天津</option>
        </select>
    </p>
    <p>
        <input type="file" name="upload">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

 從上面咱們能夠知道咱們經過標籤裏面的name屬性值獲取到的是標籤的value,當時多選的時候會獲得一個列表。

同時上傳文件咱們獲得的是一個obj咱們打印出這個obj看到的是一個上傳文件的名字,可是經過type能夠知道這個並不僅是一個文件名。

要想獲取裏面文件裏面的數據咱們使用obj.chunks()的方法獲取裏面數據,經過和操做文件句柄同樣的操做一行行的讀取裏面的數據再把這個數據寫入到文件中,記住使用'wb'的方式,這個上傳的多是圖像

經過obj.name獲取到咱們真正想知道的文件名。上面上傳文件咱們須要提早建立一個upload_dir目錄要不就會報錯。

寫視圖的方式有FBV和CBV

一、FBV

FBV --> function base view

這個寫視圖用的是函數的方式。

如:

def  函數名(request):

同時寫路由關係就是上面的方式:

from app01 import views

url(r'^login/', views.login)

 二、CBV

CBV --> class base view

使用類的方式寫視圖。

這裏的類須要繼承View類,因此咱們在視圖函數裏面須要導入

from django.views import View

class 類名(View):

寫路由關係咱們須要在路由關係中寫:

記住在視圖類的後面要加上.as_view(),下面黃色部分使咱們能夠變化的路由關係

url(r'^login/', views.Login.as_view())

 

咱們上面就是使用的FBV寫的,如今咱們使用CBV實現下登陸頁面的驗證

先在myobj/urls.py裏面代碼

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

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^index/', views.Index.as_view()),
    url(r'^login/', views.Login.as_view()),

]

 

視圖裏面的代碼

from django.shortcuts import render,redirect
from django.views import View
class Index(View):
    def get(self,request):
        return render(request,'index.html')

class Login(View):
    def get(self,request):
        return render(request,'login.html')
    def post(self,request):
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'admin' and pwd == 'admin':
            return redirect('/index/')
        else:
            return render(request,'login.html')

 

html代碼和上面的第一個登陸界面的html代碼是同樣的沒什麼區別。這個實現後的效果也是同樣的。只是不一樣形式的實現方式這個是CBV的方式實現的。

簡單分析CBV的運行的流程

咱們直接訪問頁面的時候通常都是使用get的方式提交的

當咱們輸入url他會在路由關係裏面找到相應的視圖類,咱們使用繼承的類的裏面使用了反射函數。

咱們能夠經過看繼承的父類裏面的代碼能夠知道它裏面是幫咱們作了相應的處理,反射到咱們在類裏面綁定的函數。

直接執行咱們在內中綁定的函數。就實現了整個流程。

 視圖中傳入模板的字典數據的循環取值

卸載app01/views.py中的代碼

from django.shortcuts import render
USER_DICT = {
    "k1":"root1",
    "k2":"root2",
    "k3":"root3",
    "k4":"root4",
    "k5":"root5",
}

def index(request):
    return render(request,"index.html",{"user_dict":USER_DICT})

 

index.html代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for k,row in user_dict.items  %}
            <li>{{ k }}-{{ row }}</li>
        {% endfor %}
        {% for k in user_dict %}
            <li>{{ k }}</li>
        {% endfor %}
        {% for v in user_dict.values %}
            <li>{{ v }}</li>
        {% endfor %}
    </ul>
</body>
</html>

上面咱們能夠看到我麼你能夠經過for循環dict.items取字典的鍵值對

也能夠經過for循環dict.values取字典的每個值,也能夠直接循環字典獲得字典的鍵。

 

Django的路由系統

多級路由

上面寫的都是經過主urls文件經過導入app的views來實現關於路由到視圖的關聯,也能夠稱主usrl文件爲一級路由

當咱們外部訪問的時候,會在一級路由中查找,若是想要多級路由就要在以及路由裏面導入下一級路由。

代碼爲:

from django.conf.urls import url, include

urlpatterns = [
    url(r'^cmdb/', include("app01.urls")),  
]

上面的urls咱們須要在app01下面本身建立。

先說一下當咱們輸入url的時候在路由系統裏面咱們匹配的去除掉前面域名的

如:http://127.0.0.1/cmdb/django/,咱們只會匹配後面/cmdb/django

在一級路由的時候咱們會正則匹配/cmdb/同時也去除掉前面正則匹配的這時只有/django/那會拿着這個url到app01裏面的urls裏面正則匹配相應的路由。這樣就實現了多級路由。咱們能夠認爲只要前面是/cmdb/咱們就會把剩下的路由傳遞給include的下一級路由。這個就是多級路由

 url()方法

url()方法能夠接受4個參數(regex, view, kwargs=None, name=None)能夠看出2個是必須的

regex:這個就是正則表達式的縮寫,這個就是匹配字符串或這url地址的語法。

view:指的是處理當前url請求的試圖函數。

kwargs:任意數量的關鍵字參數能夠做爲一個字典傳遞給目標視圖

name:對你的URL進行命名,讓你可以在Django的任意處,尤爲是模板內顯式地引用它。這是一個很是強大的功能,至關於給URL取了個全局變量名,不會將url匹配地址寫死。

這裏只是簡單的介紹一下這四個參數。

regex

關於regex的寫法,當一個網站的url地址太多的時候咱們就會寫的太多。咱們能夠把一些有相同特性的url寫成贊成格式:

如:url(r'^index-(\d+).html', views.index),這個就是一個正則表達式,能夠匹配這一類型的url

或者url(r'^index-(\d+)-(\d+).html', views.index),這個能夠更好的匹配相應的url

上面的這個匹配會把分組的匹配到的按位置傳送到view試圖函數。至關於他會把第一個分組匹配的看成視圖函數的一個參數傳給試圖函數,

這個若是參數的位置寫錯了就會形成後面的一系列數據錯誤,因此不推薦使用這個。

咱們可使用:url(r'^index-(?P<nid>\d+)-(?P<uid>\d+).html', views.index)

這個就是正則的給分組起一個名字,這樣咱們就會獲得一個字典咱們就能夠把這個字典傳到視圖函數裏面。

這樣咱們就能夠根據咱們起的名字來取到咱們想要的數據。

視圖函數能夠是:def 函數名(request,*args,**kwargs):pass

這樣無論咱們url裏面的分組是否起名字咱們都可以傳到後面。不過建議使用後一種方式這樣不容易出錯。

name

name是對URL路由關係進行命名,之後能夠根據此名稱生成本身想要的URL

url(r'^asdf/', views.index, name='i1'),

url(r'^qwe/(\d+)/(\d+)/', views.index, name='i2'),

url(r'^asd/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),

這個樣咱們在視圖函數裏面能夠:

from django.urls import reverse        

def func(request,*args,**kwargs):

  url1 = reverse('i1')                # 獲得的是  asdf/

  url2 = reverse(‘i2',args(1,2))          # 獲得 /qwe/1/2

  url3 = reverse('i3',kwargs{pid:1,nid:3})   # asd/1/3

在模板語言中:

{% url "i1" %}    ---生成/asdf/

{% url "i2" 1 2 %}  --生成qwe/1/2/

{% url "i3" pid=1 uid=3 %} ---生成asd/1/3/

這個的用處好比咱們本來有一個網址咱們如今改成一個新的網址,可是由於舊的網址,用的人比較多咱們就能夠利用跳轉

如:

原來的:

url(r'^qwe/(\d+)/(\d+)/', views.index),

改爲

url(r'^new_qwe(\d+)/(\d+)/', views.new_index,name='i1'),

咱們只須要在view裏面增長

from django.http import HttpResponseRedirect

from django.urls import reverse

def inde(requsrt,a,b):

  return HttpResponseRedirect(reverse('i1',args=(a,b)))

Django的ORM

一、數據庫的安裝

再說ORM的時候,咱們先說一下數據庫的安裝。

咱們打開項目的setting.py的配置文件,這個是整個個Django項目的設置中心。Django默認使用SQLite數據庫,由於Python源生支持SQLite數據庫,因此你無須安裝任何程序,就能夠直接使用它。固然,若是你是在建立一個實際的項目,可使用相似PostgreSQL的數據庫,避免之後數據庫遷移的相關問題。

在這個配置文件中咱們能夠找到以下的代碼,這個就是默認的數據庫配置,這個默認爲SQLite數據庫。

# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

 

若是咱們想要其餘的數據庫的時候咱們能夠在上面的key爲default對應的值進行配置。來鏈接你的數據庫。上面的一些參數的解釋

ENGINE(引擎):能夠是django.db.backends.sqlite3django.db.backends.postgresqldjango.db.backends.mysqldjango.db.backends.oracle等其餘的

NAME(名稱):相似Mysql數據庫管理系統中用於保存項目內容的數據庫的名字。若是你使用的是默認的SQLite,那麼數據庫將做爲一個文件將存放在你的本地機器內,此時的NAME應該是這個文件的完整絕對路徑包括文件名,默認值os.path.join(BASE_DIR, ’db.sqlite3’),將把該文件儲存在你的項目目錄下。

下面就是一個使用mysql數據庫的,由於python不支持mysql因此只能藉助pymysql來實現操做mysql

import pymysql         # 必定要添加這兩行
#  這個pymysql不屬於python內置的須要咱們本身安裝
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite',
        'HOST': '192.168.244.1',
        'USER': 'root',
        'PASSWORD': '123456',
        'PORT': '3306',
    }
}

 

咱們在操做數據庫的時候,咱們必須如今mysql中建立相應的數據庫才能操做。

還有在我本身建立的app時咱們須要把這個app加入到setting中,若是是用pycharm建立Django項目是就穿件的就不須要

使用命令建立的就須要加入:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',  # 把咱們建立的app01加入
]

 

二、建立類

 咱們在相應的app中的models.py裏面建立咱們想要的模型,在這裏面咱們全是用python代碼實現的不接觸任何的SQL語句

app01/models.py

from django.db import models

class UserInfo(models.Model):
    # Django會默認建立一個id列,而且是自增,主鍵
    # 用戶名列,字符串類型,指定長度
    username = models.CharField(max_length=32)
    # 密碼列,字符類型,指定長度
    password = models.CharField(max_length=64)

 

 這樣建立模型後,咱們須要執行相應的代碼才能把這些寫到相應的數據庫中,也就是啓動模型。

Django會作2件事。

一、建立app對應的數據庫表結構

二、爲咱們模型裏面的對象建立基於python的數據庫訪問API

這個執行的目錄就是manage.py同目錄下面。

在命令行:python3 manage.py makemigrations

經過運行makemigrations命令,至關於告訴Django你對模型有改動,而且你想把這些改動保存爲一個「遷移(migration)」。

migrations是Django保存模型修改記錄的文件,這些文件保存在磁盤上。在例子中,它就是app01/migrations/0001_initial.py,你能夠打開它看看,裏面保存的都是人類可讀而且可編輯的內容,方便你隨時手動修改。

 這裏還須要咱們把數據遷移到數據庫裏面就還須要執行

python3 manage.py migrate

這裏面由於默認爲SQLite,要想查看裏面的數據咱們可使用Navicat Premium 12這個軟件鏈接到SQLite

也能夠直接在pycharm上查看。

 

 點擊pycharm右面的有一個database而後就有上面的畫面,再把咱們和manage.py同目錄上面的db.sqlite3拖到這個框框裏面

從上面能夠看出咱們可以對數據庫進行相應的操做了。

上面就是在django裏面模型的建立以及把模型遷移到數據庫上的操做,以及查看的一些方式。

三、添加數據

使用python語句添加數據的幾種方式

1、

models.UserInfo.objects.create()

from django.shortcuts import HttpResponse
from app01 import models
def orm(request):
    models.UserInfo.objects.create(username='root', password='1234')
    return HttpResponse('ok')

 

 當咱們訪問http://127.0.0.1:8000/orm/的時候咱們就會在數據庫裏面建立該數據

注意這裏咱們在urls的路由系統裏面加了相應的路由配置

2、

obj = models.UserInfo()

obj.save()

from django.shortcuts import HttpResponse
from cmdb import models
def orm(request):
    obj = models.UserInfo(username='admin', password='1234')
    obj.save()
    return HttpResponse('ok')

  當咱們訪問http://127.0.0.1:8000/orm/的時候咱們就會在數據庫裏面建立該數據

3、

這種方式就是第一種的差很少只是咱們傳進去的是一個字典

from django.shortcuts import HttpResponse
dic = {
    'username':'qwer',
    'password':'1234'
}
# Create your views here.
from cmdb import models
def orm(request):
    models.UserInfo.objects.create(**dic)
    return HttpResponse('ok')

 

上面的字典中的key就是咱們數據庫中的列,值就是列中對應的數據。

四、數據庫數據的查詢

查詢全部:ret = models.UserInfo.objects.all()

這裏獲得的返回值爲:<QuerySet [<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]>

上面能夠知道咱們獲得一個QuerySet數據這個和列表有點相似,咱們能夠經過循環獲取它的數據

from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
from cmdb import models
def orm(request):
    ret = models.UserInfo.objects.all()
    print(ret)
    for row in ret:
        print(row)
        print(row.id,row.username,row.password)
    return HttpResponse('ok')
## 結果
<QuerySet [<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]>
UserInfo object (1)
1 root 1234
UserInfo object (2)
2 admin 1234
UserInfo object (3)
3 qwer 1234

 

能夠看出ret是一個QuerySet數據類型,循環咱們獲得的是一個object對象,咱們能夠經過object對象獲取相應的數據。

 

條件語句查詢:result =models.UserInfo.objects.filter(username="root")

查詢username爲root的用戶全部信息至關於數據庫的where username = 'root'

這個查詢出來的也是QuerySet類型的

from django.shortcuts import HttpResponse
# Create your views here.
from cmdb import models
def orm(request):
    ret = models.UserInfo.objects.filter(username='root')
    print(ret)
    print(ret[0].username)
    return HttpResponse('ok')

#結果爲
<QuerySet [<UserInfo: UserInfo object (1)>]>
root

 

上面咱們能夠看出查詢出來的仍是QuerySet數據類型,

五、刪除數據

models.UserInfo.objects.delete() 刪除全部數據

models.UserInfo.objects.filter(id=2).delete() 經過條件刪除

六、更新數據

models.UserInfo.objects.all().update(password=222)    #將全部的的密碼都更改,

models.UserInfo.objects.filter(id=2).update(password=888)  # 根據條件更新

ORM的一些補充

建立數據庫表的有哪些字符類型中的字段的參數的意思

null               -> db是否能夠爲空default            -> 默認值primary_key        -> 主鍵db_column          -> 列名db_index           -> 索引unique          -> 惟一索引unique_for_date    -> unique_for_monthunique_for_yearauto_now           -> 建立時,自動生成時間auto_now_add       -> 更新時,自動更新爲當前時間choices            -> django admin中顯示下拉框,避免連表查詢blank             -> django admin是否能夠爲空verbose_name      -> django admin顯示字段中文editable          -> django admin是否能夠被編輯help_text         -> django admin提示...
相關文章
相關標籤/搜索