Django ——自強(qiáng)學(xué)堂學(xué)習(xí)筆記

(一)、啟動服務(wù)器

E:\ScienceSoft\Python\Django\Django_project>python manage.py runserver 0.0.0.0:8
000
Performing system checks...

System check identified no issues (0 silenced).
July 22, 2017 - 17:00:33
Django version 1.11.3, using settings 'Django_project.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CTRL-BREAK.

(二)、創(chuàng)建數(shù)據(jù)庫表 或 更改數(shù)據(jù)庫表或字段

E:\ScienceSoft\Python\Django\Django_project>python manage.py makemigrations
No changes detected

E:\ScienceSoft\Python\Django\Django_project>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  No migrations to apply.

Django 1.7.1及以上 用以下命令

1. 創(chuàng)建更改的文件

python manage.py makemigrations

2. 將生成的py文件應(yīng)用到數(shù)據(jù)庫

python manage.py migrate
這種方法可以在SQL等數(shù)據(jù)庫中創(chuàng)建與models.py代碼對應(yīng)的表,不需要自己手動執(zhí)行SQL。

(三) 、使用開發(fā)服務(wù)器:python manage.py runserver
3.1清空數(shù)據(jù)庫
命令會詢問是 yes 還是 no, 選擇 yes 會把數(shù)據(jù)全部清空掉,只留下空表
python manage.py flush
3.2 創(chuàng)建超級管理員
python manage.py createsuperuser

按照提示輸入用戶名和對應(yīng)的密碼就好了郵箱可以留空,用戶名和密碼必填

修改 用戶密碼可以用:

python manage.py changepassword username
我的用戶名和密碼:sky和Q。。。。123

E:\ScienceSoft\Python\Django\Django_project>python manage.py createsuperuser
Username (leave blank to use 'administrator'): sky
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is entirely numeric.
Password:
Password (again):
This password is too common.
This password is entirely numeric.
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
Password:
Password (again):
Superuser created successfully.

(四)、安裝bpython
(五)、 Django與數(shù)據(jù)庫
Django 會自動進(jìn)入在settings.py中設(shè)置的數(shù)據(jù)庫:


問題:
1、Django入門:python manage.py dbshell錯(cuò)誤
學(xué)習(xí)SQLite是為了在Django上用,因此我更關(guān)注與Django相關(guān)的。
解決:

1、下載sqlite3【[http://www.sqlite.org/sqlite-shell-win32-x86-3071401.zip](http://www.sqlite.org/sqlite-shell-win32-x86-3071401.zip)】 
2、將sqlite3.exe文件放入(C:\Windwos\System32)中 ,如果是win 7 64位系統(tǒng)則放入C:\Windows\SysWOW64
3、E:\ScienceSoft\Python\Django\Django_project> manage.py dbshell
E:\ScienceSoft\Python\Django\Django_project>python manage.py dbshell
CommandError: You appear not to have the 'sqlite3' program installed or on your
path.

E:\ScienceSoft\Python\Django\Django_project>python manage.py dbshell
SQLite version 3.7.14.1 2012-10-04 19:37:12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

django-admin.py dbshell可以打開sqlite3命令行shell。該命令需要DJANGO_SETTINGS_MODULE中指定相應(yīng)的數(shù)據(jù)庫。它與整個(gè)django相關(guān)的。如果打開項(xiàng)目指定的數(shù)據(jù)庫shell,需要利用manage.py 代替上面的django-admin.py。
如沒安裝sqlite3,會提示:
Error: You appear not to have the 'sqlite3' program installed or no your path.
由于python只是集成了sqlite3的庫文件,并不提供sqlite3程序。要用它的shell要安裝下。
sqlite3一些常見命令
SQL;直接執(zhí)行sql語句。
.help 幫助
.database 查看數(shù)據(jù)庫
.exit .quit 退出
.table 查看表
.dump table 查看SQL語句

(六) 、 Django 視圖與網(wǎng)址
urls.py :網(wǎng)址
views.py:正則表達(dá)式對應(yīng)于其中的一個(gè)函數(shù)(或者generic類)
1.創(chuàng)建項(xiàng)目Django_project
django-admin startproject Django_project
Django_project
├── manage.py
└── Django_project
├── init.py
├── settings.py
├── urls.py
└── wsgi.py
我們會發(fā)現(xiàn)執(zhí)行命令后,新建了一個(gè) Django_project 目錄,其中還有一個(gè)Django_project 目錄,這個(gè)子目錄 Django_project中是一些項(xiàng)目的設(shè)置 settings.py 文件,總的urls配置文件 urls.py 以及部署服務(wù)器時(shí)用到的 wsgi.py 文件, init.py 是python包的目錄結(jié)構(gòu)必須的,與調(diào)用有關(guān)。
我們到外層那個(gè) Django_project目錄下(不是Django_project中的Django_project目錄)

(七)、 新建一個(gè)應(yīng)用(app), 名稱叫 learn

image.png

1.添加app到settings.py中
settings.py:


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 添加部分如下:添加新的app

    'learn',
]

新建的 app 如果不加到 INSTALL_APPS 中的話, django 就不能自動找到app中的模板文件(app-name/templates/下的文件)和靜態(tài)文件(app-name/static/中的文件)

2.定義視圖函數(shù)(訪問頁面時(shí)的內(nèi)容)
learn目錄下的view.py:

from django.shortcuts import render

# Create your views here.
# 定義視圖函數(shù)(訪問頁面時(shí)的內(nèi)容)
from django.http import HttpResponse


def index(request):
    return HttpResponse(u"我的新建 APP !")

第一行是聲明編碼為utf-8, 因?yàn)槲覀冊诖a中用到了中文,如果不聲明就報(bào)錯(cuò).

第二行引入HttpResponse,它是用來向網(wǎng)頁返回內(nèi)容的,
就像Python中的 print 一樣,只不過 HttpResponse 是把內(nèi)容顯示到網(wǎng)頁上。

3.怎么讓網(wǎng)址和函數(shù)關(guān)聯(lián)起來呢?定義視圖函數(shù)相關(guān)的URL(網(wǎng)址) (即規(guī)定 訪問什么網(wǎng)址對應(yīng)什么內(nèi)容)
Django_project\Django_project下的urls.py:

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

# 添加
from learn import views as learn_views # 取別名

urlpatterns = [
    # 添加
    url(r'^$', learn_views.index), # new

    url(r'^admin/', admin.site.urls),

]

一共修改了settings.py, views.py,urls.py,apps.py
啟動服務(wù)器 python manage.py runserver,http://127.0.0.1:8000/在瀏覽器中打開后顯示:views.py中的內(nèi)容

image.png

Django中的 urls.py 用的是正則進(jìn)行匹配的,如果不熟悉,您可以學(xué)習(xí)正則表達(dá)式以及Python正則表達(dá)式。
(七)、開始再新建項(xiàng)目Developer
在網(wǎng)頁上做加減法
修改Developer/calc下的views.py:

from django.shortcuts import render

# Create your views here.
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
# 在網(wǎng)頁上做加減法
def add(request):

    a = request.GET['a']

    b= request.GET['b']

    c = int(a)+int(b)

    return HttpResponse(str(c))

# 注:request.GET 類似于一個(gè)字典,更好的辦法
# 是用 request.GET.get('a', 0) 當(dāng)沒有傳遞 a 的時(shí)候默認(rèn) a 為 0

在修改Developer下的urls.py:
添加一個(gè)網(wǎng)址來對應(yīng)我們剛才新建的視圖函數(shù)

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

from calc  import views as calc_views
urlpatterns = [
 # 添加一個(gè)網(wǎng)址來對應(yīng)learn下的views.py中新建的視圖函數(shù)
    url(r'^add/$', calc_views.add, name='add')
#  name相當(dāng)于“給網(wǎng)址取了個(gè)名字”,只要這個(gè)名字不變,網(wǎng)址變了也能通過名字獲取到
    #url(r'^admin/', admin.site.urls),
]

啟動服務(wù)器 python manage.py runserver 8001,http://127.0.0.1:8001/add/在瀏覽器中打開后顯示:views.py中的內(nèi)容

image.png

這是因?yàn)槲覀儾]有傳值進(jìn)去,我們在后面加上?a=4&b=5,即訪問 http://127.0.0.1:8001/add/?a=4&b=5
就可以看到網(wǎng)頁上顯示一個(gè) 9,試著改變一下a和b對應(yīng)的值試試看?
注意:如果打開8000端口會訪問失敗,原因是前面創(chuàng)建的項(xiàng)目已將占用了端口8000
所以此處改為8001

image.png
image.png

2.采用 /add/3/4/ 這樣的網(wǎng)址的方式
修改 calc/views.py文件,再新定義一個(gè)add2 函數(shù)
views.py:

ws here.
from django.http import HttpResponse
# 在網(wǎng)頁上做加減法
def add(request):

    a = request.GET['a']

    b= request.GET['b']

    c = int(a)+int(b)

    return HttpResponse(str(c))

def add2(request, a, b):

    c = int(a) + int(b)

    return HttpResponse(str(c))

接著修改Developer/urls.py 文件,再添加一個(gè)新的 url


可以看到網(wǎng)址中多了 (\d+), 正則表達(dá)式中 \d 代表一個(gè)數(shù)字,+ 代表一個(gè)或多個(gè)前面的字符,寫在一起 \d+ 就是一個(gè)或多個(gè)數(shù)字,用括號括起來的意思是保存為一個(gè)子組
每一個(gè)子組將作為一個(gè)參數(shù),被 views.py 中的對應(yīng)視圖函數(shù)接收。
http://127.0.0.1:8001/add/24/5/在瀏覽器中打開:

image.png

4.創(chuàng)建首頁視圖和url
Developer下的urls.py:

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

from calc  import views as calc_views
urlpatterns = [

 # 添加一個(gè)網(wǎng)址來對應(yīng)learn下的views.py中新建的視圖函數(shù)
    url(r'^add/$', calc_views.add, name='add'),
    #url(r'^admin/', admin.site.urls),
    # 再添加一個(gè)新的url
    url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
    # index是views.py中的函數(shù)名
    url(r'^$', calc_views.index, name='home')
    ]

先建一個(gè)首頁的視圖和url修改 calc/views.py:

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
# render是渲染模板

# Create your views here.

def  index(request):
    return render(request, 'home.html')
# 在網(wǎng)頁上做加減法
def add(request):

    a = request.GET['a']

    b= request.GET['b']

    c = int(a)+int(b)

    return HttpResponse(str(c))

def add2(request, a, b):

    c = int(a) + int(b)

    return HttpResponse(str(c))

將 'calc' 這個(gè) app 加入到 Developer/settings.py 中
settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'calc',
]

在 calc 這個(gè) app 中新建一個(gè) templates 文件夾,在templates中新建一個(gè) home.html (關(guān)于模板更詳細(xì)的可以稍后看下一節(jié))

文件 calc/templates/home.html 中寫入以下內(nèi)容(保存時(shí)用 utf8 編碼)

home.html:

<!DOCTYPE html>
<html>
<head>
    <title>Django學(xué)習(xí)</title>
</head>
<body>
<a href="/add/24/5/">計(jì)算 24+5</a>
</body>
</html>

修改Developer/urls.py:

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

from calc  import views as calc_views
urlpatterns = [

 # 添加一個(gè)網(wǎng)址來對應(yīng)learn下的views.py中新建的視圖函數(shù)
    url(r'^add/$', calc_views.add, name='add'),
    #url(r'^admin/', admin.site.urls),
    # 再添加一個(gè)新的url
    url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
    # index是views.py中的函數(shù)名
    url(r'^$', calc_views.index, name='home')
    ]

運(yùn)行開發(fā)服務(wù)器,我們訪問 http://127.0.0.1:8001/可以看到:

image.png

當(dāng)我點(diǎn)擊計(jì)算24+5后,會顯示計(jì)算結(jié)果
我們計(jì)算加法的時(shí)候用的是 /add/4/5/ ,后來需求發(fā)生變化,比如改成 /4_add_5/,但在網(wǎng)頁中,代碼中很多地方都寫死的 /add/4/5/,比如模板中可能是這么寫的
<a href="/add/4/5/">計(jì)算 4+5</a>
如果這樣寫“死網(wǎng)址”,會使得在改了網(wǎng)址(正則)后,模板(template),視圖(views.py,用以用于跳轉(zhuǎn)),模型(models.py,可以用用于獲取對象對應(yīng)的地址)用了此網(wǎng)址的,都得進(jìn)行相應(yīng)的更改,修改的代價(jià)很大,一不小心,有的地方?jīng)]改過來,就不能用了。我們先說一下如何用 Python 代碼獲取對應(yīng)的網(wǎng)址(可以用在 views.py,models.py等各種需要轉(zhuǎn)換得到網(wǎng)址的地方):

我們在終端上輸入(推薦安裝 bpython, 這樣Django會用 bpython的 shell)
http://www.jb51.net/article/79498.htm
我使用這種方法安裝bpython——克隆bpython的Git倉庫:git clone https://github.com/bpython/bpython/
bpython是一個(gè)Python Shell。

如果你系統(tǒng)里安裝了Python3,它才能以Python3運(yùn)行。

建議使用virtualenv,自己編譯一套py3的環(huán)境,然后在py3的環(huán)境上運(yùn)行bpython。

使用py3的virtualenv

首先編譯Python3.X: py3

生成py3 virtualenv

virtualenv py3env -p py3/bin/python3

使用新的virtualenv環(huán)境

source py3env/bin/activate

使用bpython

bpython
Windows環(huán)境64位機(jī)器

使用pip安裝curses

pip install E:\downloads\curses-2.2-cp27-none-win_amd64.whl
curses-2.2-cp27-none-win_amd64.whl下載地址
http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses
x下載后,打開cmd,進(jìn)入文件的存放目錄,運(yùn)行結(jié)果如下
E:\ScienceSoft\Python>pip install curses-2.2-cp35-none-win_amd64.whl
Processing e:\sciencesoft\python\curses-2.2-cp35-none-win_amd64.whl
Installing collected packages: curses
Successfully installed curses-2.2
注意:cp35是python3.5
cp27是python2.7
http://blog.csdn.net/c465869935/article/details/51586077
ImportError: No module named fcntl錯(cuò)誤解決, 將資源fcntl.py下載下來,放到python的安裝目錄下的\Lib目錄內(nèi)即可。我的是放到D:\Python27\Lib目錄下了。
我的是C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Lib
結(jié)果又遇到ImportError: No module named 'termios'
百度后有的說需要用cygwin. cygwin是一個(gè)在windows平臺上運(yùn)行的unix模擬環(huán)境
https://jingyan.baidu.com/article/48a42057accae3a92525045a.html
https://jingyan.baidu.com/article/9c69d48f9ecb0613c8024e5d.html
https://jingyan.baidu.com/article/6b97984d83dfe51ca2b0bf0e.html
如何測試cygwin是否成功?https://www.zhihu.com/question/24213717
查閱 Cygwin 包列表。https://www.ibm.com/developerworks/cn/aix/library/au-spunix_cygwin/#resources
小結(jié):
ctrl+f:網(wǎng)站彈出搜索框快捷鍵
http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses,再安裝bpython
bpython一直安裝不了,所以只好安裝了ipython
如下:pip install ipython

image.png
image.png
image.png

退出用quit;
我們在終端上輸入(推薦安裝 bpython, 這樣Django會用 bpython的 shell,但是如下圖啟動的是ipython的shell,即因?yàn)槲野惭b的是ipython)
python manage.py shell


image.png
image.png

我的項(xiàng)目是在Developer目錄下,該目錄下有calc文件


E:\ScienceSoft\Python\Django\Django_project\Developer>python manage.py shell
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AM
D64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from django.core.urlresolvers import reverse
manage.py:1: RemovedInDjango20Warning: Importing from django.core.urlresolvers i
s deprecated in favor of django.urls.
  #!/usr/bin/env python

In [2]: from django.urls import reverse

In [3]: reverse('add2', args(4,5))
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-e32011ea2241> in <module>()
----> 1 reverse('add2', args(4,5))

NameError: name 'args' is not defined

In [4]: reverse('add2', args=(444,555))
Out[4]: '/add/444/555/'

In [5]: reverse('add2', args=(4,5))
Out[5]: '/add/4/5/'

In [6]:

現(xiàn)在只要對應(yīng)的 url 的name不改,就不用改代碼中的網(wǎng)址
因?yàn)槲覀兪褂胷everse來接收url中的name作為第一個(gè)參數(shù),通過reverse()來獲取
對應(yīng)的網(wǎng)址(這個(gè)網(wǎng)址可以用來跳轉(zhuǎn),也可以用來計(jì)算相關(guān)頁面的地址)
在網(wǎng)頁模板中也是一樣,可以很方便的使用。
template/home.html:

<!DOCTYPE html>
<html>
<head>
    <title>Django學(xué)習(xí)</title>
</head>
<body>
<a href="/add/24/5/">計(jì)算 24+5</a>
<!--
不帶參數(shù)的:
{% url 'name' %}
帶參數(shù)的:參數(shù)可以是變量名
{% url 'name' 參數(shù) %}
-->
<a href="{% url 'add2' 34 5 %}">link</a>
<!--
這樣就可以通過{% url 'add2' 4 5 %}獲取到對應(yīng)的網(wǎng)址/add/4/5
-->
</body>
</html>

當(dāng) urls.py 進(jìn)行更改,前提是不改 name(這個(gè)參數(shù)設(shè)定好后不要輕易改),獲取的網(wǎng)址也會動態(tài)地跟著變注意看重點(diǎn) add 變成了 new_add,但是后面的 name='add2' 沒改,這時(shí) {% url 'add2' 4 5 %} 就會渲染對應(yīng)的網(wǎng)址成 /new_add/4/5/

urls.py :

"""Developer URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/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

from calc  import views as calc_views
urlpatterns = [

 # 添加一個(gè)網(wǎng)址來對應(yīng)learn下的views.py中新建的視圖函數(shù)
    url(r'^add/$', calc_views.add, name='add'),
    #url(r'^admin/', admin.site.urls),
    # 再添加一個(gè)新的url
    # 當(dāng)urls.py更改,前提是不改name
    # url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
    
    url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
  
    # index是views.py中的函數(shù)名
    url(r'^$', calc_views.index, name='home')
    ]

用在 views.py 或 models.py 等地方的 reverse函數(shù),同樣會根據(jù) name 對應(yīng)的url獲取到新的網(wǎng)址
想要改網(wǎng)址的時(shí)候,修改 urls.py 中的正則表達(dá)式部分(url 參數(shù)第一部分),name 不變的前提下,其它地方都不需要修改

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

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

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

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
# render是渲染模板
# 跳轉(zhuǎn)
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse


# Create your views here.

def  index(request):
    return render(request, 'home.html')
# 在網(wǎng)頁上做加減法
def add(request):

    a = request.GET['a']

    b= request.GET['b']

    c = int(a)+int(b)

    return HttpResponse(str(c))

def add2(request, a, b):

    c = int(a) + int(b)

    return HttpResponse(str(c))

# 寫一個(gè)跳轉(zhuǎn)的函數(shù),讓以前的 /add/3/4/自動跳轉(zhuǎn)到現(xiàn)在新的網(wǎng)址

def old_add2_redirect(request, a, b):

    return HttpResponseRedirect(

        reverse('add2', args=(a, b))

        )

urls.py:

"""Developer URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/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

from calc  import views as calc_views
urlpatterns = [

 # 添加一個(gè)網(wǎng)址來對應(yīng)learn下的views.py中新建的視圖函數(shù)
    url(r'^add/$', calc_views.add, name='add'),
    #url(r'^admin/', admin.site.urls),
    # 再添加一個(gè)新的url
    # 當(dāng)urls.py更改,前提是不改name
    # url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
    # 跳轉(zhuǎn)
    url(r'^add/(\d+)/(/d+)/$', calc_views.old_add2_redirect),
#     TypeError: old_add2_redirect() missing 3 required positional arguments: 'reques
# ', 'a', and 'b'
#  url(r'^add/(\d+)/(/d+)/$', calc_views.old_add2_redirect())這樣寫會報(bào)上述錯(cuò)
    url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
  
    # index是views.py中的函數(shù)名
    url(r'^$', calc_views.index, name='home')
    ]

這樣,假如用戶收藏夾中有 /add/4/5/ ,訪問時(shí)就會自動跳轉(zhuǎn)到新的 /new_add/4/5/ 了
開始可能覺得直接寫網(wǎng)址簡單,但是用多了你一定會發(fā)現(xiàn),用“死網(wǎng)址”的方法很糟糕。
報(bào)錯(cuò)的時(shí)候根據(jù)網(wǎng)頁的提示更改,如下:

image.png
image.png

在前面的幾節(jié)中我們都是用簡單的 django.http.HttpResponse 來把內(nèi)容顯示到網(wǎng)頁上
本節(jié)將講解如何使用渲染模板的方法來顯示內(nèi)容

三、第三個(gè)項(xiàng)目:新建項(xiàng)目progect3
1.創(chuàng)建project3 項(xiàng)目和應(yīng)用(名稱為learn3)如下:

E:\ScienceSoft\Python\Django>django-admin startproject project3

E:\ScienceSoft\Python\Django>cd project3

E:\ScienceSoft\Python\Django\project3>python manage.py startapp learn3

  1. 把 learn 加入到 settings.INSTALLED_APPS中
    settings.py:
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'learn3',
]

3.打開 learn3/views.py 寫一個(gè)首頁的視圖
views.py:

from django.shortcuts import render

# Create your views here.
def home(request):

    return render(request, 'home.html')
  1. 在 learn目錄下新建一個(gè) templates 文件夾,里面新建一個(gè) home.html
    目錄的結(jié)構(gòu)是這樣的:
    progect3
    ├── learn3
    │ ├── init.py
    │ ├── admin.py
    │ ├── migrations
    │ │ └── init.py
    │ ├── models.py
    │ ├── templates
    │ │ └── home.html
    │ ├── tests.py
    │ └── views.py
    ├── manage.py
    └── progect3
    ├── init.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
    4 directories, 12 files
    本節(jié)將講解如何使用渲染模板的方法來顯示內(nèi)容。
  2. 在 home.html 中寫一些內(nèi)容
    home.html:
<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
  </body>
</html>
  1. 將視圖函數(shù)對應(yīng)到網(wǎng)址,更改 project3/urls.py
    urls.py:
from django.conf.urls import url
from django.contrib import admin
# 1
from learn3 import views as learn3_views
urlpatterns = [
    url(r'^$', learn3_views.home, name='home'),
    url(r'^admin/', admin.site.urls),
]


python manage.py runserver

image.png

模板補(bǔ)充知識:

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

nav.html, bottom.html, #html

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

注意:模板一般放在app下的templates中,Django會自動去這個(gè)文件夾中找。

templates/base.html:


其它的頁面繼承自 base.html 就好了,繼承后的模板也可以在 block 塊中 include 其它的模板文件
如我們的首頁頁面home.html,繼承base.html,寫法如下:
base.html:

<!DOCTYPE html>
<html>
<head>
    
    <title>{% block title%}默認(rèn)標(biāo)題{% endblock %} - 自強(qiáng)學(xué)堂</title>
</head>
<body>

{%  include 'nav.html' %}

{% block content %}
<div>這里是默認(rèn)內(nèi)容,所有繼承自這個(gè)模板的,如果不覆蓋就顯示這里的默認(rèn)內(nèi)容</div>
{% endclock %}

{% include 'bottom.html' %}

{% include '#html' %}
</body>
</html>

home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
{% extends 'base.html' %}

{% block title %}自強(qiáng)學(xué)堂——Django學(xué)習(xí)筆記首頁頁面{% endblock %}

{% block content %}
{% include 'ad.html' %}

這里是首頁,歡迎光臨

{% endblock %}
  </body>
}

</html>

但 假如我們每個(gè)app的templates中都有一個(gè) index.html,當(dāng)我們在views.py中使用的時(shí)候,直接寫一個(gè) render(request, 'index.html'),Django 能不能找到當(dāng)前 app 的 templates 文件夾中的 index.html 文件夾呢?(答案是不一定能,有可能找錯(cuò))
Django 模板查找機(jī)制: Django 查找模板的過程是在每個(gè) app 的 templates 文件夾中找(而不只是當(dāng)前 app 中的代碼只在當(dāng)前的 app 的 templates 文件夾中找)。各個(gè) app 的 templates 形成一個(gè)文件夾列表,Django 遍歷這個(gè)列表,一個(gè)個(gè)文件夾進(jìn)行查找,當(dāng)在某一個(gè)文件夾找到的時(shí)候就停止,所有的都遍歷完了還找不到指定的模板的時(shí)候就是 Template Not Found (過程類似于Python找包)。這樣設(shè)計(jì)有利當(dāng)然也有弊,有利是的地方是一個(gè)app可以用另一個(gè)app的模板文件,弊是有可能會找錯(cuò)了。所以我們使用的時(shí)候在 templates 中建立一個(gè) app 同名的文件夾,這樣就好了

這就需要把每個(gè)app中的 templates 文件夾中再建一個(gè) app 的名稱,僅和該app相關(guān)的模板放在 app/templates/app/ 目錄下面,

templates 文件夾中再建一個(gè) app
例如:項(xiàng)目 project3 有兩個(gè) app,分別為 tutorial 和 learn3

project3
├── tutorial
│ ├── init.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── tutorial
│ │ ├── index.html
│ │ └── search.html
│ ├── tests.py
│ └── views.py
├── learn3
│ ├── init.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── tryit
│ │ ├── index.html
│ │ └── poll.html
│ ├── tests.py
│ └── views.py
├── manage.py
└── zqxt
├── init.py
├── settings.py
├── urls.py
└── wsgi.py

這樣,使用的時(shí)候,模板就是 "tutorial/index.html" 和 "learn3/index.html" 這樣有app作為名稱的一部分,就不會混淆。

五、Django 模板進(jìn)階:
本節(jié)主要講 Django模板中的循環(huán),條件判斷,常用的標(biāo)簽,過濾器的使用
1.列表,字典,類的實(shí)例的使用

2.循環(huán):迭代顯示列表,字典等中的內(nèi)容

3.條件判斷:判斷是否顯示該內(nèi)容,比如判斷是手機(jī)訪問,還是電腦訪問,給出不一樣的代碼。

4.標(biāo)簽:for,if 這樣的功能都是標(biāo)簽。

5.過濾器:管道符號后面的功能,比如{{ var|length }},求變量長度的 length 就是一個(gè)過濾器。
如果需要將一個(gè)或多個(gè)變量共享給多個(gè)網(wǎng)頁或者所有網(wǎng)頁使用,比如在網(wǎng)頁上顯示來訪者的IP,這個(gè)可以使用 Django 上下文渲染器 來做。
實(shí)例一,顯示一個(gè)基本的字符串在網(wǎng)頁上
(1)home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂


{{ string }}
 </body>
</html>

(2)views.py:

from django.shortcuts import render

# Create your views here.
def home(request):
    # 實(shí)例一,顯示一個(gè)基本的字符串在網(wǎng)頁上
    string = u"我在自強(qiáng)學(xué)堂學(xué)習(xí)Django,用它來建網(wǎng)站"
# 在視圖中我們傳遞了一個(gè)字符串(名稱是 string )到模板 home.html
    return render(request, 'home.html', {'string': string})

(3)http://127.0.0.1:8000/

image.png

實(shí)例二,講解了基本的 for 循環(huán) 和 List內(nèi)容的顯示
views.py:

from django.shortcuts import render

# Create your views here.
def home(request):
    Learn3 = ["HTML", "CSS", "jQuery", "Python", "Django"]
    return render(request, 'home.html', {'Learn3': Learn3})
        # 實(shí)例一,顯示一個(gè)基本的字符串在網(wǎng)頁上
    #string = u"我在自強(qiáng)學(xué)堂學(xué)習(xí)Django,用它來建網(wǎng)站"
# 在視圖中我們傳遞了一個(gè)字符串(名稱是 string )到模板 home.html
# 實(shí)例二

在視圖中我們傳遞了一個(gè)List到模板 home.html,在模板中這樣使用它:
home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
教程列表
{%  for i in Learn3 %}
{{ i }}
for 循環(huán)要有一個(gè)結(jié)束標(biāo)記
{% endfor %}
 </body>

</html>
image.png

簡單總結(jié)一下:一般的變量之類的用 {{ }}(變量),功能類的,比如循環(huán),條件判斷是用 {% %}(標(biāo)簽)
home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
教程列表
{%  for i in Learn3 %}
{{ i }}

{% endfor %}
 </body>

</html>
image.png

實(shí)例三,顯示字典中內(nèi)容:
views.py:

from django.shortcuts import render

# Create your views here.
def home(request):
    # 實(shí)例二
    # Learn3 = ["HTML", "CSS", "jQuery", "Python", "Django"]

    # 實(shí)例三:顯示字典中的內(nèi)容

    info_dict = {'site': u'自強(qiáng)學(xué)堂', 'content': u'各種IT技術(shù)教程'}
    return render(request, 'home.html', {'info_dict': info_dict})
        # 實(shí)例一,顯示一個(gè)基本的字符串在網(wǎng)頁上
    #string = u"我在自強(qiáng)學(xué)堂學(xué)習(xí)Django,用它來建網(wǎng)站"
# 在視圖中我們傳遞了一個(gè)字符串(名稱是 string )到模板 home.html

home.html

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
站點(diǎn):
{{ info_dict.site }}

內(nèi)容:
{{ info_dict.content }}
</body>
}

</html>

在模板中取字典的鍵是用點(diǎn)info_dict.site,而不是Python中的 info_dict['site'],效果如下——???

image.png

還可以這樣遍歷字典:
views.py:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
{% for key, value in info_dict.items %}
    {{ key }}: {{ value }}
{% endfor %}

</html>

image.png

其實(shí)就是遍歷這樣一個(gè) List: [('site', u'自強(qiáng)學(xué)堂'), ('content', u'各種IT技術(shù)教程')]

實(shí)例四,在模板進(jìn)行 條件判斷和 for 循環(huán)的詳細(xì)操作:
views.py:

from django.shortcuts import render

# Create your views here.
def home(request):
    # 實(shí)例二
    # Learn3 = ["HTML", "CSS", "jQuery", "Python", "Django"]

    # 實(shí)例三:顯示字典中的內(nèi)容

    # info_dict = {'site': u'自強(qiáng)學(xué)堂', 'content': u'各種IT技術(shù)教程'}
    # 實(shí)例四
    List = map(str, range(100)) # 一個(gè)長度為100的 List
    return render(request, 'home.html', {'List': List})
        # 實(shí)例一,顯示一個(gè)基本的字符串在網(wǎng)頁上
    #string = u"我在自強(qiáng)學(xué)堂學(xué)習(xí)Django,用它來建網(wǎng)站"
# 在視圖中我們傳遞了一個(gè)字符串(名稱是 string )到模板 home.html

假如我們想用逗號將這些元素連接起來:
home.py:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>
Django學(xué)習(xí)教程之一:自強(qiáng)學(xué)堂
{% for item in List %}
    {{ item }},
{% endfor %}

</html>
image.png

我們會發(fā)現(xiàn)最后一個(gè)元素后面也有一個(gè)逗號,這樣肯定不爽,如果判斷是不是遍歷到了最后一個(gè)元素了呢?

用變量 forloop.last 這個(gè)變量,如果是最后一項(xiàng)其為真,否則為假,更改如下

{% for item in List %}
    {{ item }}{% if not forloop.last %}, {% endif %}
{% endfor %}
image.png
image.png

在for循環(huán)中還有很多有用的東西,如下:
當(dāng)列表中可能為空值時(shí)用 for empty

views.py:

from django.shortcuts import render

# Create your views here.
def home(request):
    

    athlete_list = ['sky:' '1', 'kk:''2', 'ko:' '3']
    return render(request, 'home.html', {'athlete_list ': athlete_list })

home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
  <body>

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
 {% empty %}
    <li>抱歉,列表為空</li>
 {% endfor %}
</ul>
image.png

上述問題提示列表為空,但是我的列表中是有值得,這是為什么???

實(shí)例五,模板上得到視圖對應(yīng)的網(wǎng)址:

django.VERSION
(1, 11, 3, 'final', 0)
django.VERSION
(1, 11, 3, 'final', 0)
django.get_version()
'1.11.3'
Django By Example》第一章 中文翻譯 - 知乎專欄

image.png

實(shí)例七,模板中 獲取當(dāng)前網(wǎng)址,當(dāng)前用戶等:
1.修改settings.py:
Django 1.8 及以后 修改 settings.py (Django 1.11 中新建的項(xiàng)目已經(jīng)默認(rèn)加上了)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # 1.11的版本 Django
                'django.template.context_processors.request',
            ],
        },
    },

然后在 模板中我們就可以用 request 了。一般情況下,推薦用 render 而不是用 render_to_response
7.1 獲取當(dāng)前用戶:
home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
<body>

{{ request.user }}
</body>
</html>
image.png

home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
<body>

{{ request.user }}

{% if request.user.is_authenticated %}
    {{ request.user.username }}, 您好!
{% else %}
     請登錄,這里放登陸鏈接
{% endif %}
</body>
</html>
image.png

獲取當(dāng)前網(wǎng)址:
home.html:

<!DOCTYPE html>
<html>
  <head>
    <title>如何使用渲染模板的方法來顯示內(nèi)容</title>

  </head>
<body>

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

比如我們可以判斷 delete 參數(shù)是不是 1 來刪除當(dāng)前的頁面內(nèi)容。

六、Django 模型(數(shù)據(jù)庫)

Django 模型是與數(shù)據(jù)庫相關(guān)的,與數(shù)據(jù)庫相關(guān)的代碼一般寫在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等數(shù)據(jù)庫,只需要在settings.py中配置即可,不用更改models.py中的代碼,豐富的API極大的方便了使用。
1.新建項(xiàng)目和應(yīng)用

E:\ScienceSoft\Python\Django>django-admin.py startproject learn_models

E:\ScienceSoft\Python\Django>cd learn_models

E:\ScienceSoft\Python\Django\learn_models>django-admin.py startapp people

E:\ScienceSoft\Python\Django\learn_models>


  1. 添加應(yīng)用

將我們新建的應(yīng)用(people)添加到 settings.py 中的 INSTALLED_APPS中,也就是告訴Django有這么一個(gè)應(yīng)用。
settings.py:

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'people',
]

3.修改models.py
之前的項(xiàng)目實(shí)例中,沒有修改models.py文件,即模型
我們打開 people/models.py 文件,修改其中的代碼如下:
修改models.py:

from django.db import models

# Create your models here.
class Person(models.Model):

    name = models.CharField(max_length=30)

    age = models.IntegerFiled()

我們新建了一個(gè)Person類,繼承自models.Model, 一個(gè)人有姓名和年齡。

這里用到了兩種Field,更多Field類型可以參考教程最后的鏈接。

  1. 創(chuàng)建數(shù)據(jù)表
    我們來同步一下數(shù)據(jù)庫(我們使用默認(rèn)的數(shù)據(jù)庫 SQLite3,無需配置)
E:\ScienceSoft\Python\Django\learn_models>python manage.py makemigrations
Migrations for 'people':
  people\migrations\0001_initial.py
    - Create model Person
E:\ScienceSoft\Python\Django\learn_models>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, people, sessions
Running migrations:
  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 auth.0008_alter_user_username_max_length... OK
  Applying people.0001_initial... OK
  Applying sessions.0001_initial... OK

我們會看到,Django生成了一系列的表,也生成了我們新建的people_person這個(gè)表,那么如何使用這個(gè)表呢?

如何使用生成的表

  1. 使用 Django 提供的 QuerySet API
    Django提供了豐富的API, 下面演示如何使用它。

E:\ScienceSoft\Python\Django\learn_models>python manage.py shell
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AM
D64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from people.models import Person

In [2]: Person.objects.create(name="LiJun")
---------------------------------------------------------------------------
IntegrityError                            Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\ut
ils.py in execute(self, sql, params)
     64             else:
---> 65                 return self.cursor.execute(sql, params)
     66

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\sq
lite3\base.py in execute(self, query, params)
    327         query = self.convert_query(query)
--> 328         return Database.Cursor.execute(self, query, params)
    329

IntegrityError: NOT NULL constraint failed: people_person.age

The above exception was the direct cause of the following exception:

IntegrityError                            Traceback (most recent call last)
<ipython-input-2-68274b20ae3e> in <module>()
----> 1 Person.objects.create(name="LiJun")

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\mana
ger.py in manager_method(self, *args, **kwargs)
     83         def create_method(name, method):
     84             def manager_method(self, *args, **kwargs):
---> 85                 return getattr(self.get_queryset(), name)(*args, **kwarg
s)
     86             manager_method.__name__ = method.__name__
     87             manager_method.__doc__ = method.__doc__

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\quer
y.py in create(self, **kwargs)
    392         obj = self.model(**kwargs)
    393         self._for_write = True
--> 394         obj.save(force_insert=True, using=self.db)
    395         return obj
    396

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base
.py in save(self, force_insert, force_update, using, update_fields)
    805
    806         self.save_base(using=using, force_insert=force_insert,
--> 807                        force_update=force_update, update_fields=update_f
ields)
    808     save.alters_data = True
    809

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base
.py in save_base(self, raw, force_insert, force_update, using, update_fields)
    835             if not raw:
    836                 self._save_parents(cls, using, update_fields)
--> 837             updated = self._save_table(raw, cls, force_insert, force_upd
ate, using, update_fields)
    838         # Store the database on which the object was saved
    839         self._state.db = using

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base
.py in _save_table(self, raw, cls, force_insert, force_update, using, update_fie
lds)
    921
    922             update_pk = meta.auto_field and not pk_set
--> 923             result = self._do_insert(cls._base_manager, using, fields, u
pdate_pk, raw)
    924             if update_pk:
    925                 setattr(self, meta.pk.attname, result)

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base
.py in _do_insert(self, manager, using, fields, update_pk, raw)
    960         """
    961         return manager._insert([self], fields=fields, return_id=update_p
k,
--> 962                                using=using, raw=raw)
    963
    964     def delete(self, using=None, keep_parents=False):

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\mana
ger.py in manager_method(self, *args, **kwargs)
     83         def create_method(name, method):
     84             def manager_method(self, *args, **kwargs):
---> 85                 return getattr(self.get_queryset(), name)(*args, **kwarg
s)
     86             manager_method.__name__ = method.__name__
     87             manager_method.__doc__ = method.__doc__

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\quer
y.py in _insert(self, objs, fields, return_id, raw, using)
   1074         query = sql.InsertQuery(self.model)
   1075         query.insert_values(fields, objs, raw=raw)
-> 1076         return query.get_compiler(using=using).execute_sql(return_id)
   1077     _insert.alters_data = True
   1078     _insert.queryset_only = False

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\sql\
compiler.py in execute_sql(self, return_id)
   1097         with self.connection.cursor() as cursor:
   1098             for sql, params in self.as_sql():
-> 1099                 cursor.execute(sql, params)
   1100             if not (return_id and cursor):
   1101                 return

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\ut
ils.py in execute(self, sql, params)
     78         start = time()
     79         try:
---> 80             return super(CursorDebugWrapper, self).execute(sql, params)
     81         finally:
     82             stop = time()

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\ut
ils.py in execute(self, sql, params)
     63                 return self.cursor.execute(sql)
     64             else:
---> 65                 return self.cursor.execute(sql, params)
     66
     67     def executemany(self, sql, param_list):

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\utils.py in
 __exit__(self, exc_type, exc_value, traceback)
     92                 if dj_exc_type not in (DataError, IntegrityError):
     93                     self.wrapper.errors_occurred = True
---> 94                 six.reraise(dj_exc_type, dj_exc_value, traceback)
     95
     96     def __call__(self, func):

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\utils\six.py i
n reraise(tp, value, tb)
    683             value = tp()
    684         if value.__traceback__ is not tb:
--> 685             raise value.with_traceback(tb)
    686         raise value
    687

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\ut
ils.py in execute(self, sql, params)
     63                 return self.cursor.execute(sql)
     64             else:
---> 65                 return self.cursor.execute(sql, params)
     66
     67     def executemany(self, sql, param_list):

~\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\sq
lite3\base.py in execute(self, query, params)
    326             return Database.Cursor.execute(self, query)
    327         query = self.convert_query(query)
--> 328         return Database.Cursor.execute(self, query, params)
    329
    330     def executemany(self, query, param_list):

IntegrityError: NOT NULL constraint failed: people_person.age

In [3]: Person.objects.create(name="LiJun", age=24)
Out[3]: <Person: Person object>

In [4]: Person.objects.get(name="LiJun")
Out[4]: <Person: Person object>

In [5]:

查詢:我們用了一個(gè) .objects.get() 方法查詢出來符合條件的對象
但是大家注意到了沒有,查詢結(jié)果中顯示<Person: Person object>,這里并沒有顯示出與WeizhongTu的相關(guān)信息,如果用戶多了就無法知道查詢出來的到底是誰,查詢結(jié)果是否正確,我們重新修改一下 people/models.py

  1. 使用 Django 提供的 QuerySet API
    Django提供了豐富的API, 下面演示如何使用它。
    $ python manage.py shell

from people.models import Person
Person.objects.create(name="WeizhongTu", age=24)
<Person: Person object>

我們新建了一個(gè)用戶WeizhongTu 那么如何從數(shù)據(jù)庫是查詢到它呢?

1
2
3

Person.objects.get(name="WeizhongTu")
<Person: Person object>

我們用了一個(gè) .objects.get() 方法查詢出來符合條件的對象,但是大家注意到了沒有,查詢結(jié)果中顯示<Person: Person object>,這里并沒有顯示出與WeizhongTu的相關(guān)信息,

如果用戶多了就無法知道查詢出來的到底是誰,查詢結(jié)果是否正確,
我們重新修改一下 people/models.py:

models/py:



按 CTRL + C 退出當(dāng)前的 Python shell, 重復(fù)上面的操作,我們就可以看到:

name 和 age 等字段中不能有 __(雙下劃線,因?yàn)樵贒jango QuerySet API中有特殊含義(用于關(guān)系,包含,不區(qū)分大小寫,以什么開頭或結(jié)尾,日期的大于小于,正則等)

也不能有Python中的關(guān)鍵字,name 是合法的,student_name 也合法,但是student__name不合法,try, class, continue 也不合法,因?yàn)樗荘ython的關(guān)鍵字( import keyword; print(keyword.kwlist) 可以打出所有的關(guān)鍵字)

http://sqlitebrowser.org/假設(shè)你新建一個(gè)protject和一個(gè)app后沒有進(jìn)行其他操作設(shè)置(setting.py),那么默認(rèn)就是使用sqlite3,同步數(shù)據(jù)庫之后,會生成一個(gè)數(shù)據(jù)庫db.sqlite3,一方面可以將你在models.py中定義的類映射到數(shù)據(jù)庫的表中(會在mongoDB那篇中貼圖說明),一個(gè)類對應(yīng)一個(gè)表

  1. 問題描述
    在配置完數(shù)據(jù)庫mysite/settings.py后,通常需要運(yùn)行

python manage.py syncdb

為數(shù)據(jù)庫中每個(gè)應(yīng)用建立一個(gè)數(shù)據(jù)庫表。
然而如果你安裝的Django Version >= 1.9,那么會出現(xiàn)如下問題:

gzxultra@gzxultraPC:~/django_try/mysite$ python manage.py syncdbUnknown command: 'syncdb'Type 'manage.py help' for usage.gzxultra@gzxultraPC:~/django_try/mysite$ python manage.py syncdbpython manage.py syncdbUnknown command: 'syncdbpython'Type 'manage.py help' for usage.

  1. 解決方法
    在stackoverflow上找到原因和解決方法:
    syncdb is deprecated because of the migration system.
    Now you can log your changes using makemigrations. This transforms your model changes into python code to make them deployable to another databases.
    After you created the migrations you have to apply them: migrate.
    So instead of using syncdb you should use makemigrations and then migrate.

簡言之:在Django 1.9及未來的版本種使用migrate代替syscdb.
./manage.py migrate

E:\ScienceSoft\Python\Django\learn_models> python manage.py syncdb
Unknown command: 'syncdb'
Type 'manage.py help' for usage.

E:\ScienceSoft\Python\Django\learn_models>manage.py help

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[contenttypes]
    remove_stale_contenttypes

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    test
    testserver

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver

E:\ScienceSoft\Python\Django\learn_models>
E:\ScienceSoft\Python\Django\learn_models>python manage.py syncdb
Unknown command: 'syncdb'
Type 'manage.py help' for usage.

E:\ScienceSoft\Python\Django\learn_models>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, people, sessions
Running migrations:
  No migrations to apply.
  Your models have changes that are not yet reflected in a migration, and so won
't be applied.
  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage
.py migrate' to apply them.

E:\ScienceSoft\Python\Django\learn_models>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容