Django基礎(chǔ)學(xué)習(xí)

感謝自強(qiáng)學(xué)堂

[TOC]

Django簡介

urls.py

網(wǎng)址入口端圈,關(guān)聯(lián)到對應(yīng)的view.py中的一個函數(shù)(或者generic類)盒音,訪問網(wǎng)址就對應(yīng)一個函數(shù)

view.py

處理用戶發(fā)出的請求扣溺,從urls.py中對應(yīng)過來,通過選人templates中的網(wǎng)頁镐确,可將內(nèi)容顯示包吝,比如,登陸后的用戶名源葫,用戶請求的數(shù)據(jù)诗越,輸出到網(wǎng)頁

models.py

與數(shù)據(jù)庫關(guān)聯(lián),存入或讀取數(shù)據(jù)的時候會用到這個

forms.py

表單息堂,用戶在瀏覽器上輸入數(shù)據(jù)提交嚷狞,對數(shù)據(jù)的驗證工作以及輸入框的生成等工作

templates文件夾

views.py 中的函數(shù)渲染templates中的Html模板,得到動態(tài)內(nèi)容的網(wǎng)頁荣堰,當(dāng)然可以用緩存來提高速度床未。

admin.py

后臺,可以用很少的代碼量持隧,擁有一個強(qiáng)大的后臺

settings.py

Django 的設(shè)置即硼,配置文件,比如Debug開關(guān)屡拨,靜態(tài)文件位置等

Django環(huán)境搭建

Django 1.5.x 支持 Python 2.6.5 Python 2.7, Python 3.2 和 3.3.

Django 1.6.x 支持 Python 2.6.X, 2.7.X, 3.2.X 和 3.3.X

Django 1.7.x 支持 Python 2.7, 3.2, 3.3, 和 3.4 (注意:Python 2.6 不支持了)

Django 1.8.x 支持 Python 2.7, 3.2, 3.3, 3.4 和 3.5. (長期支持版本 LTS)

Django 1.9.x 支持 Python 2.7, 3.4 和 3.5. 不支持 3.3 了

Django 1.10.x 支持 Python 2.7, 3.4 和 3.5.

Django 1.11.x 下一個長期支持版本只酥,將于2017年4月發(fā)布

更詳細(xì)的可以參考這里一般來說,選擇長期支持版本比較好呀狼。

使用最新版本的問題就是裂允,可能要用到的一些第三方插件沒有及時更新,無法正常使用這些三方包哥艇。

如果是學(xué)習(xí)绝编,可以選擇目前的 Django 1.8.x 來進(jìn)行,遇到問題也容易找到答案貌踏。

當(dāng)然如果需要新版本的功能也可以使用新版本十饥,畢竟 Django 1.9 以后admin界面還是更漂亮些

Django基礎(chǔ)部分

安裝Django

安裝pip

ubuntu sudo apt-get install python-pip

centos yum -y install python-pip

升級pip

pip install --upgrade pip

利用pip安裝Django

(sudo) pip install Django
或者 (sudo) pip install Django==1.8.16 或者 pip install Django==1.10.3

搭建多個互不干擾的開發(fā)環(huán)境

# 安裝:
(sudo) pip install virtualenv
mkdir myproject
cd myproject

virtualenv --no-site-packages test

#命令virtualenv就可以創(chuàng)建一個獨立的Python運行環(huán)境,我們還加上了參數(shù)--no-site-packages祖乳,這樣逗堵,已經(jīng)安裝到系統(tǒng)Python環(huán)境中的所有第三方包都不會復(fù)制過來,這樣眷昆,我們就得到了一個不帶任何第三方包的“干凈”的Python運行環(huán)境蜒秤。

source test/bin/activate
#命令行提示符的最前方汁咏,會提示當(dāng)前所在的python環(huán)境

#然后就可以在此環(huán)境下 進(jìn)行開發(fā)/測試等

deactivate  #退出環(huán)境

Django的基本命令(請牢牢記住,不能tab)

新建一個django project
django-admin.py startproject zixue
新建app
python manage.py startapp app-name
或 django-admin.py startapp app-name

#一般一個項目有多個app, 當(dāng)然通用的app也可以在多個項目中使用作媚。
同步數(shù)據(jù)庫
python manage.py syncdb
 
#注意:Django 1.7.1及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate

#這種方法可以創(chuàng)建表攘滩,當(dāng)你在models.py中新增了類時,運行它就可以自動在數(shù)據(jù)庫中創(chuàng)建表了纸泡,不用手動創(chuàng)建漂问。

#備注:對已有的 models 進(jìn)行修改,Django 1.7之前的版本的Django都是無法自動更改表結(jié)構(gòu)的弟灼,不過有第三方工具 south,
使用開發(fā)服務(wù)器

開發(fā)服務(wù)器级解,即開發(fā)時使用,一般修改代碼后會自動重啟田绑,方便調(diào)試和開發(fā)勤哗,但是由于性能問題,建議只用來測試掩驱,不要用在生產(chǎn)環(huán)境芒划。

python manage.py runserver
 
# 當(dāng)提示端口被占用的時候,可以用其它端口:
python manage.py runserver 8001
python manage.py runserver 9999
(當(dāng)然也可以kill掉占用端口的進(jìn)程)
 
# 監(jiān)聽所有可用 ip (電腦可能有一個或多個內(nèi)網(wǎng)ip欧穴,一個或多個外網(wǎng)ip民逼,即有多個ip地址)
python manage.py runserver 0.0.0.0:8000
# 如果是外網(wǎng)或者局域網(wǎng)電腦上可以用其它電腦查看開發(fā)服務(wù)器
# 訪問對應(yīng)的 ip加端口,比如 http://172.16.20.2:8000
清空數(shù)據(jù)庫
python manage.py flush
創(chuàng)建超級管理員
python manage.py createsuperuser
 
# 按照提示輸入用戶名和對應(yīng)的密碼就好了郵箱可以留空涮帘,用戶名和密碼必填
 
# 修改 用戶密碼可以用:
python manage.py changepassword username

導(dǎo)入導(dǎo)出數(shù)據(jù)

python manage.py dumpdata appname > appname.json
python manage.py loaddata appname.json
Django羨慕的環(huán)境終端
python manage.py shell
數(shù)據(jù)庫命令行
python manage.py dbshell

Django 會自動進(jìn)入在settings.py中設(shè)置的數(shù)據(jù)庫拼苍,如果是 MySQL 或 postgreSQL,會要求輸入數(shù)據(jù)庫用戶密碼。
在這個終端可以執(zhí)行數(shù)據(jù)庫的SQL語句调缨。如果您對SQL比較熟悉疮鲫,可能喜歡這種方式。
更多命令
終端上輸入 python manage.py 可以看到詳細(xì)的列表弦叶,在忘記子名稱的時候特別有用俊犯。

Django的視圖與網(wǎng)址

創(chuàng)建項目
django-admin.py startproject mysite

創(chuàng)建成功后,目錄如下

mysite
├── manage.py
└── mysite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
    
新建了一個 mysite 目錄伤哺,其中還有一個 mysite 目錄燕侠,這個子目錄 mysite 中是一些項目的設(shè)置settings.py 文件,總的urls配置文件 urls.py 以及部署服務(wù)器時用到的 wsgi.py 文件立莉, __init__.py 是python包的目錄結(jié)構(gòu)必須的绢彤,與調(diào)用有關(guān)。
新建應(yīng)用(app) 名字叫l(wèi)earn
python manage.py startapp learn   #learn只是一個app的名稱

把我們新定義的app加到settings.py中的INSTALL_APPS

mysite/mysite/settings.py

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'learn',
)

#備注,這一步是干什么呢? 新建的 app 如果不加到 INSTALL_APPS 中的話, django 就不能自動找到app中的模板文件(app-name/templates/下的文件)和靜態(tài)文件(app-name/static/中的文件) , 后面你會學(xué)習(xí)到它們分別用來干什么.
定義視圖函數(shù) (訪問頁面的內(nèi)容)

修改 應(yīng)用 learn 中的view.py

#coding:utf-8
from django.http import HttpResponse

def index(request):
    return HttpResponse(u'歡迎')
    
#第一行是聲明編碼為utf-8, 因為我們在代碼中用到了中文,如果不聲明就報錯.
#第二行引入HttpResponse蜓耻,它是用來向網(wǎng)頁返回內(nèi)容的茫舶,就像Python中的 print 一樣,只不過 HttpResponse 是把內(nèi)容顯示到網(wǎng)頁上媒熊。
#我們定義了一個index()函數(shù)奇适,第一個參數(shù)必須是 request,與網(wǎng)頁發(fā)來的請求有關(guān)芦鳍,request 變量里面包含get或post的內(nèi)容嚷往,用戶瀏覽器,系統(tǒng)等信息#在里面(后面會講柠衅,先了解一下就可以)皮仁。
#函數(shù)返回了一個 HttpResponse 對象,可以經(jīng)過一些處理菲宴,最終顯示幾個字到網(wǎng)頁上贷祈。
#那問題來了,我們訪問什么網(wǎng)址才能看到剛才寫的這個函數(shù)呢喝峦?怎么讓網(wǎng)址和函數(shù)關(guān)聯(lián)起來呢势誊?
定義視圖函數(shù)相關(guān)的URL(即,訪問什么網(wǎng)址谣蠢,對應(yīng)什么內(nèi)容)

打開mysite下的urls.py

#Django 1.7

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
 
urlpatterns = patterns('',
    url(r'^$', 'learn.views.index'),  # new
    # url(r'^blog/', include('blog.urls')),
 
    url(r'^admin/', include(admin.site.urls)),
)
#Django1.8 以上

from django.conf.urls import url
from django.contrib import admin

from learn import views as learn_views  # new
 
urlpatterns = [
    url(r'^$', learn_views.index),  # new
    url(r'^admin/', admin.site.urls),
]
#開啟python測試
python manage.py runserver
#允許遠(yuǎn)程訪問
python manager.py runserver 0.0.0.0:8000 (指定IP和端口)

視圖與網(wǎng)址進(jìn)階

新建項目
新建應(yīng)用

同上

修改應(yīng)用下的views.py
from django.shortcuts import render
from django.http import HttpResponse
 
def add(request):
    a = request.GET['a']
    b = request.GET['b']
    c = int(a)+int(b)
    return HttpResponse(str(c))
    
    #注:request.GET 類似于一個字典粟耻,更好的辦法是用 request.GET.get('a', 0) 當(dāng)沒有傳遞 a 的時候默認(rèn) a 為 0
修改項目下的urls.py
from django.conf.urls import url
from django.contrib import admin

from learn import views as learn_views
from calc import views as calc_views

urlpatterns = [
    url(r'^add/$',calc_views.add,name='add'),
    url(r'^$',learn_views.index),
    url(r'^admin/', admin.site.urls),
]
打開網(wǎng)址

IP:8000/add/?a=1&b=2

采用add/2/4的方式

進(jìn)入cala/views.py 定義函數(shù)

def add2(request,a,b):
    c = int(a) + int(b)
    return HttpResponse(str(c))

修改項目下的urls.py

Django 1.7.X

    url(r'^add/(\d+)/(\d+)/$', 'calc.views.add2', name='add2'),

Django 1.8+

    url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
    
    #我們可以看到網(wǎng)址中多了 (\d+), 正則表達(dá)式中 \d 代表一個數(shù)字,+ 代表一個或多個前面的字符眉踱,寫在一起 \d+ 就是一個或多個數(shù)字挤忙,用括號括起來的意思是保存為一個子組(更多知識請參見 Python 正則表達(dá)式),每一個子組將作為一個參數(shù)谈喳,被 views.py 中的對應(yīng)視圖函數(shù)接收册烈。
訪問 http://127.0.0.1:8000/add/4/5/ 就可以看到和剛才同樣的效果

URL name詳解

url(r'^add/$', calc_views.add,name='add'), 這里的name='add' 是用來干什么的呢?

簡單的來說婿禽,name可以在template,models赏僧,views中得到對應(yīng)的網(wǎng)址,相當(dāng)于給網(wǎng)址去了名字谈宛,只要名字不變次哈,網(wǎng)址變不變都是可以獲取到的

修改calc/views.py (應(yīng)用calc已經(jīng)在setting.py中INSTALLED_APPS導(dǎo)入,不然模板是找不到的)

from django.http import HttpResponse
from django.shortcuts import render
 
def index(request):
    return render(request, 'home.html')
...

#render 是渲染模板

然后新建templates文件夾,在新建home.html

<!DOCTYPE html>
<html>
<head>
    <title>自強(qiáng)學(xué)堂</title>
</head>
<body>
<a href="/add/4/5/">計算 4+5</a>
</body>
</html>

修改項目中的urls.py

...
from learn import views as learn_views
from calc import views as calc_views

urlpatterns = [
    url(r'^$',calc_views.index,name='home'),
    url(r'^add/$',calc_views.add,name='add'),
    url(r'^add/(\d+)/(\d+)/$',calc_views.add2,name='add2'),
    url(r'^admin/', admin.site.urls),
]

然后運行服務(wù),訪問頁面就會出現(xiàn) 計算4+5 的鏈接

<a href="/add/4/5/">計算 4+5</a>

如果這樣寫“死網(wǎng)址”,會使得在改了網(wǎng)址(正則)后吆录,模板(template)窑滞,視圖(views.py,用以用于跳轉(zhuǎn))恢筝,模型(models.py哀卫,可以用用于獲取對象對應(yīng)的地址)用了此網(wǎng)址的,都得進(jìn)行相應(yīng)的更改撬槽,修改的代價很大此改,一不小心,有的地方?jīng)]改過來侄柔,就不能用了共啃。

那么有沒有更優(yōu)雅的方式來解決這個問題呢占调?
不帶參數(shù)的:
{% url 'name' %}
帶參數(shù)的:參數(shù)可以是變量名
{% url 'name' 參數(shù) %}
 
例如:
<a href="{% url 'add2' 4 5 %}">link</a>

當(dāng) urls.py 進(jìn)行更改,前提是不改 name(這個參數(shù)設(shè)定好后不要輕易改)移剪,獲取的網(wǎng)址也會動態(tài)地跟著變究珊,比如改成:

url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2')

#add 變成了 new_add,但是后面的 name='add2' 沒改纵苛,這時 {% url 'add2' 4 5 %} 就會渲染對應(yīng)的網(wǎng)址成 /new_add/4/5/

另外剿涮,比如用戶收藏夾中收藏的URL是舊的,如何讓以前的 /add/3/4/自動跳轉(zhuǎn)到現(xiàn)在新的網(wǎng)址呢攻人?

要知道Django不會幫你做這個取试,這個需要自己來寫一個跳轉(zhuǎn)方法

具體思路是,在 views.py 寫一個跳轉(zhuǎn)的函數(shù):

from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse  # django 1.4.x - django 1.10.x
#  from django.urls import reverse  # new in django 1.10.x
 
def old_add2_redirect(request, a, b):
    return HttpResponseRedirect(
        reverse('add2', args=(a, b))
    )

urls.py中

url(r'^add/(\d+)/(\d+)/$', calc_views.old_add2_redirect),
url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),

這樣怀吻,假如用戶收藏夾中有 /add/4/5/ 瞬浓,訪問時就會自動跳轉(zhuǎn)到新的 /new_add/4/5/ 了

templates

創(chuàng)建一個項目和app

django-admin.py startproject zqxt_tmpl
cd zqxt_tmpl
python manage.py startapp learn

把 learn 加入到 settings.INSTALLED_APPS中

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'learn',
)

打開 learn/views.py 寫一個首頁的視圖

from django.shortcuts import render
 
def home(request):
    return render(request, 'home.html')

創(chuàng)建templates/home.html

然后將輸入和網(wǎng)址對應(yīng)

from django.conf.urls import include, url
from django.contrib import admin
from learn import views as learn_views
 
 
urlpatterns = [
    url(r'^$', learn_views.home, name='home'),
    url(r'^admin/', include(admin.site.urls)),
]

#Django1.10+
#url(r'^admin/', admin.site.urls),  #include
項目中有多個應(yīng)用,所以就會有多個templates以及多個index.html

默認(rèn)情況下Django是不會去區(qū)分的,最先找到那個就顯示那個,所以如果為了區(qū)分的話

就在各個應(yīng)用的templates下進(jìn)行在劃分

project
├── app1
|....
│   ├── templates
│   │   └── app1
│   │       ├── index.html
│   │       └── search.html
├── app2
|.....
│   ├── templates
│   │   └── app2
│   │       ├── index.html
│   │       └── poll.html
模版補(bǔ)充知識點

網(wǎng)站模板的設(shè)計,一般的烙博,我們做網(wǎng)站有一些通用的部分瑟蜈,比如導(dǎo)航,底部渣窜,訪問統(tǒng)計代碼等等

可以寫一個 base.html 來包含這些通用文件(include)

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}默認(rèn)標(biāo)題{% endblock %} - test</title>
</head>
<body>
 
{% include 'nav.html' %}
 
{% block content %}
<div>這里是默認(rèn)內(nèi)容铺根,所有繼承自這個模板的,如果不覆蓋就顯示這里的默認(rèn)內(nèi)容乔宿。</div>
{% endblock %}
 
{% include 'bottom.html' %}
 
{% include '#html' %}
 
</body>
</html>


#如果需要位迂,寫足夠多的 block 以便繼承的模板可以重寫該部分,include 是包含其它文件的內(nèi)容详瑞,就是把一些網(wǎng)頁共用的部分拿出來掂林,重復(fù)利用,改動的時候也方便一些坝橡,還可以把廣告代碼放在一個單獨的html中泻帮,改動也方便一些,在用到的地方include進(jìn)去计寇。其它的頁面繼承自 base.html 就好了锣杂,繼承后的模板也可以在 block 塊中 include 其它的模板文件。

templatesde 進(jìn)階

主要講解模板中的循環(huán)番宁,條件判斷元莫,常用的標(biāo)簽,過濾器的使用

基本字節(jié)的顯示

views.py

# -*- coding: utf-8 -*-
from django.shortcuts import render
 
def home(request):
    string = u"學(xué)習(xí)Django蝶押,用它來建網(wǎng)站"
    return render(request, 'home.html', {'string': string})

#在視圖中我們傳遞了一個字符串名稱是 string(引號內(nèi)的表示可悲html調(diào)用的) 到模板 home.html

home.html

{{ string }}
for循環(huán)

views.py

def home(request):
    TutorialList = ["HTML", "CSS", "jQuery", "Python", "Django"]
    return render(request, 'home.html', {'TutorialList': TutorialList})

home.html

{% for i in TutorialList %}
{{ i }}
{% endfor %}

for循環(huán)要有個結(jié)束標(biāo)記

一般的變量聲明使用{{}}

功能性的 比如循環(huán)踱蠢,條件判斷等使用{% %}

顯示字典的內(nèi)容

views.py

def home(request):
    info_dict = {'site': u'學(xué)堂', 'content': u'IT技術(shù)教程'}
    return render(request, 'home.html', {'info_dict': info_dict})

home.html

站點:{{ info_dict.site }} 內(nèi)容:{{ info_dict.content }}

遍歷字典

{% for key, value in info_dict.items %}
    {{ key }}: {{ value }}
{% endfor %}
條件判斷和 for 循環(huán)

views.py

def home(request):
    List = map(str, range(100))# 一個長度為100的 List
    return render(request, 'home.html', {'List': List})

home.html

{% for item in List %}
    {{ item }}, #每次結(jié)束都會在值得后面添加最后,最后一個依然會添加 99,
{% endfor %}    

所以棋电,如何判讀是不是最后一次遍歷呢

forloop.last變量 判斷是否為最后一項茎截,如果是則為真苇侵,反之。

{% for item in List %}
    {{ item }}{% if not forloop.last %}, {% endif %} ##判斷不是最后一個則加逗號
{% endfor %}    

for循環(huán)的其他變量

變量 描述
forloop.counter 索引從1開始計算
forloop.counter0 索引從0開始計算
forloop.revcounter 索引最大長度到1
forloop.revcounter0 索引最大長度到0
forloop.first 遍歷元素為第一項時企锌,返回真
forloop.last 遍歷元素為最后一項衅檀,返回真
forloop.parentloop 用在嵌套for循環(huán)中,獲取上一層for循環(huán)的forloop

當(dāng)列表可能為空的時候用 for empty

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}
    <li>抱歉霎俩,列表為空</li>
{% endfor %}
</ul>
模板上得到視圖對應(yīng)的網(wǎng)址
# views.py
def add(request, a, b):
    c = int(a) + int(b)
    return HttpResponse(str(c))

# urls.py
urlpatterns = patterns('',
    url(r'^add/(\d+)/(\d+)/$', 'app.views.add', name='add'),
)
 
# template html
{% url 'add' 4 5 %}

#name 的方便之處。
#當(dāng)urls文件發(fā)生改變的生后沉眶,并不需要去修改html
#因為html中我們使用的是name   也就是add

還可以使用 as 語句將內(nèi)容取別名(相當(dāng)于定義一個變量)

{% url 'some-url-name' arg arg2 as the_url %}
 
<a href="{{ the_url }}">鏈接到:{{ the_url }}</a>
模板中使用邏輯操作

==, !=, >=, <=, >, < 這些比較都可以在模板中使用

{% if var >= 90 %}
成績優(yōu)秀打却,自強(qiáng)學(xué)堂你沒少去吧!學(xué)得不錯
{% elif var >= 80 %}
成績良好
{% elif var >= 70 %}
成績一般
{% elif var >= 60 %}
需要努力
{% else %}
不及格啊谎倔,大哥柳击!多去自強(qiáng)學(xué)堂學(xué)習(xí)啊片习!
{% endif %}

and, or, not, in, not in 也可以在模板中使用

{% if num <= 100 and num >= 0 %}
num在0到100之間
{% else %}
數(shù)值不在范圍之內(nèi)捌肴!
{% endif %}

判斷是否在某個列表中

{% if 'ZILI' in List %}
自強(qiáng)學(xué)堂在名單中
{% endif %}
模板中獲取當(dāng)前網(wǎng)址,當(dāng)前用戶名等

修改setting

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                ...
                'django.template.context_processors.request',
                ...
            ],
        },
    },
]

然后在模板中就可以調(diào)用了

獲取用戶

{{ request.user }}

判斷登錄

{% if request.user.is_authenticated %}
    {{ request.user.username }}藕咏,您好状知!
{% else %}
    請登陸,這里放登陸鏈接
{% endif %}

獲取網(wǎng)址

{{ request.path}}

獲取當(dāng)前get 參數(shù)

{{ request.GET.urlencode}}

合并到一起舉例

<a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">當(dāng)前網(wǎng)址加參數(shù) delete</a>

模型(數(shù)據(jù)庫)

Django模型適合數(shù)據(jù)庫相關(guān)的孽查,與數(shù)據(jù)庫相關(guān)的代碼一般寫在models.py中饥悴,Django支持 sqlite3,Mysql盲再,PostgreSQL等數(shù)據(jù)庫西设,只要在setting.py中進(jìn)行配置即可

django-admin.py startproject learn_models # 新建一個項目
cd learn_models # 進(jìn)入到該項目的文件夾
django-admin.py startapp people # 新建一個 people 應(yīng)用(app)

一個項目包含多個應(yīng)用,一個應(yīng)用也可以在多個項目中

添加新的項目到settings.py -- INSTALLED_APPS下

修改models.py

與數(shù)據(jù)庫相關(guān)的代碼一般寫在models.py中

from django.db import models
 
class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    
#新建了一個Person類答朋,繼承自models.Model, 一個人有姓名和年齡贷揽。這里用到了Field,


#上面代碼其實就相當(dāng)于原生sql

CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(30) NOT NULL,
    "age" int() NOT NULL
);

表名person_person由Django自動生成:項目名稱+下劃線+小寫類名

同步數(shù)據(jù)庫

(默認(rèn)使用SQLite3.0 無需配置)

Django 1.9 默認(rèn)使用
python manage.py makemigrations
python manage.py migrate
#同步數(shù)據(jù)庫 migrate代替老版本的syscdb
#這兩行命令會對models.py 進(jìn)行檢測梦碗,自動發(fā)現(xiàn)需要更改的禽绪,應(yīng)用到數(shù)據(jù)庫中去。
127.0.0.1:8000/admin就可以看到簡易的CMS系統(tǒng)了

同步數(shù)據(jù)庫命令返回值

[root/myProject/learn_models] ]$python manage.py makemigrations
Migrations for 'people':
  0001_initial.py:
    - Create model Person
[root/myProject/learn_models] ]$python manage.py migrate
Operations to perform:
  Apply all migrations: people, sessions, auth, contenttypes, admin
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying people.0001_initial... OK
  Applying sessions.0001_initial... OK
[root/myProject/learn_models] ]$


#創(chuàng)建superuser
python manage.py createsuperuser
Username (leave blank to use 'root'): 
Email address: ****@qq.com
Password: 
Password (again): 
Superuser created successfully.

#此時我們登錄 ipaddress:8000/admin  就能看到簡單的CMS
Django shell操作數(shù)據(jù)表

Django中的交互式shell來進(jìn)行數(shù)據(jù)庫的增刪改查等操作

增加 查詢
python manage.py shell
#數(shù)據(jù)增加
In [1]: from people.models import Person

In [2]: Person.objects.create(name='lizili',age=18)#新加數(shù)據(jù)
Out[2]: <Person: Person object>
#數(shù)據(jù)庫查詢
#查詢所有叉弦,返回一個列表丐一,無對象返回空
In [6]: Person.objects.all()
Out[6]: [<Person: Person object>]

#查詢指定對象
In [4]: a=Person.objects.get(id=1)
In [17]: a.name
Out[17]: 'lizili'

#每次都要賦值才能查找,很麻煩淹冰,所以可以去modules.py中對語句進(jìn)行修改
from django.db import models
# Create your models here.
class Person(models.Model):
    name =models.CharField(max_length=30)
    age = models.IntegerField()
    def __str__(self):
        return u'name:%s , age:%s' % (self.name,self.age)

#這樣每次就可以直接查詢了
In [1]: from people.models import Person
In [2]: Person.objects.get(id=1)
Out[2]: <Person: name:lizili , age:26>
新建數(shù)據(jù)
#1
Person.objects.create(name=name,age=age)
#2
p = Person(name="WZ", age=23)
p.save()
#3
p = Person(name="TWZ")
p.age = 23
p.save()

#4這種方法是防止重復(fù)很好的方法库车,但速度要相對慢些
#返回一個元組,第一個為Person對象樱拴,第二個為True或False, 新建時返回的是True, 已經(jīng)存在時返回False.
Person.objects.get_or_create(name="WZT", age=23)

查詢數(shù)據(jù)
Person.objects.all()#查詢所有
Person.objects.all()[:10] #切片操作柠衍,獲取10個人洋满,不支持負(fù)索引,切片可以節(jié)約內(nèi)存
Person.objects.get(name='lizili') #關(guān)鍵字

#get方法
#get是用來獲取一個對象的珍坊,如果需要獲取滿足條件的一些人牺勾,就要用到filter

#filter方法
Person.objects.filter(name="abc") # 等于Person.objects.filter(name__exact="abc") 名稱嚴(yán)格等于 "abc" 的人
Person.objects.filter(name__iexact="abc") # 名稱為 abc 但是不區(qū)分大小寫,可以找到 ABC, Abc, aBC阵漏,這些都符合條件
Person.objects.filter(name__contains="abc") # 名稱中包含 "abc"的人
Person.objects.filter(name__icontains="abc") #名稱中包含 "abc"驻民,且abc不區(qū)分大小寫
Person.objects.filter(name__regex="^abc") # 正則表達(dá)式查詢
Person.objects.filter(name__iregex="^abc")# 正則表達(dá)式不區(qū)分大小寫
#filter是找出滿足條件的,當(dāng)然也有排除符合某條件的
Person.objects.exclude(name__contains="WZ") # 排除包含 WZ 的Person對象
Person.objects.filter(name__contains="abc").exclude(age=23) # 找出名稱含有abc, 但是排除年齡是23歲的
自定義Field

更多Field

以后補(bǔ)

數(shù)據(jù)表的更改

當(dāng)數(shù)據(jù)庫設(shè)計完后履怯,發(fā)現(xiàn)不滿意回还,需要更改,添加/刪除字段叹洲。

Django 1.7+

#直接修改models.py 然后執(zhí)行以下語句即可
python manage.py makemigrations
python manage.py migrate

#會出現(xiàn)一下提示柠硕,選 1
# 1) Provide a one-off default now (will be set on all existing rows)
# 2) Quit, and let me add a default in models.py
#新增了字段,但是原來已經(jīng)的數(shù)據(jù)沒有這個字段运提,
#當(dāng)你這個字段沒有默認(rèn)值蝗柔,又不能為空的時候它就不知道怎么做
#需要選擇 1 來指定一個 “一次性的值” 給已有字段。
QuerySet API

數(shù)據(jù)庫接口相關(guān)的接口(QuerySet API)

從數(shù)據(jù)庫中查詢出來的結(jié)果一般是一個集合民泵,這個集合叫做 QuerySet

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末癣丧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子栈妆,更是在濱河造成了極大的恐慌坎缭,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件签钩,死亡現(xiàn)場離奇詭異掏呼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铅檩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門憎夷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昧旨,你說我怎么就攤上這事拾给。” “怎么了兔沃?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵蒋得,是天一觀的道長。 經(jīng)常有香客問我乒疏,道長额衙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮窍侧,結(jié)果婚禮上县踢,老公的妹妹穿的比我還像新娘。我一直安慰自己伟件,他們只是感情好硼啤,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斧账,像睡著了一般谴返。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咧织,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天亏镰,我揣著相機(jī)與錄音,去河邊找鬼拯爽。 笑死,一個胖子當(dāng)著我的面吹牛钧忽,可吹牛的內(nèi)容都是我干的毯炮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼耸黑,長吁一口氣:“原來是場噩夢啊……” “哼桃煎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起大刊,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤为迈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缺菌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葫辐,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年伴郁,在試婚紗的時候發(fā)現(xiàn)自己被綠了耿战。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡焊傅,死狀恐怖剂陡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狐胎,我是刑警寧澤鸭栖,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站握巢,受9級特大地震影響晕鹊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一捏题、第九天 我趴在偏房一處隱蔽的房頂上張望玻褪。 院中可真熱鬧,春花似錦公荧、人聲如沸带射。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窟社。三九已至,卻和暖如春绪钥,著一層夾襖步出監(jiān)牢的瞬間灿里,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工程腹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留匣吊,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓寸潦,卻偏偏與公主長得像色鸳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子见转,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容