Django回顧之_02_Django的基本使用

#4. 虛擬環境 ##4.1 概念 以前安裝python包的命令: sudo pip3 install 包名 包的安裝路徑:/usr/local/lib/python3.5/dist-packagescss

在同一個python環境中安裝同一個包的不一樣版本,後安裝的包會把原來安裝的包覆蓋掉。這樣,若是同一臺機器上兩個項目依賴於相同包的不一樣版本,則會致使一些項目運行失敗。
解決的方案就是:虛擬環境。

虛擬環境是真實python環境的複製版本。 在虛擬環境中使用的python是複製的python,安裝python包也是安裝在複製的python中。 ##4.2 安裝和配置 安裝虛擬環境的命令:html

  • 1)sudo pip install virtualenv #安裝虛擬環境
  • 2)sudo pip install virtualenvwrapper #安裝虛擬環境擴展包
  • 3)編輯/home目錄下面的.bashrc文件,添加下面兩行。
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
  • 4)使用source .bashrc使其生效一下。 ##4.3 使用python

  • 建立虛擬環境命令:mkvirtualenv 虛擬環境名mysql

  • 建立python3虛擬環境:mkvirtualenv -p python3 evn_py3web

    • 建立python3虛擬環境名,# 在建立虛擬環境時,必須保證有網
  • 進入虛擬環境工做:workon 虛擬環境名正則表達式

  • 查看機器上有多少個虛擬環境:workon 空格 + 兩個tab鍵sql

  • 退出虛擬環境:deactivateshell

  • 刪除虛擬環境:rmvirtualenv 虛擬環境名數據庫

  • 虛擬環境下安裝包的命令:pip install 包名
    注意:不能使用sudo pip install 包名,這個命令會把包安裝到真實的主機環境上而不是安裝到虛擬環境中。django

  • 查看虛擬環境中安裝了哪些python包:

pip list
pip freeze
  • 安裝django環境:pip install django==3.0.3
    • 若是網很差,會報錯:在python中安裝包出現Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))

-- 參考連接1

pip install django==3.0.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

拓展: apt-get install 軟件 pip install python包名 #5. 項目建立 ##5.1 建立Django項目

  • 命令:django-admin startproject 項目名(test1)

    注意:建立應用必須先進入虛擬環境。

  • tree可查看項目目錄

  • 項目目錄以下:

    • __init__.py: 說明test1是一個python包。
    • settings.py: 項目的配置文件。
    • urls.py: 進行url路由的配置。
    • wsgi.py: web服務器和Django交互的入口。
    • manage.py: 項目的管理文件。 ##5.2 建立Django應用 一個項目由不少個應用組成的,每個應用完成一個功能模塊
  • 建立應用的命令以下:python manage.py startapp 應用名(booktest) 注意:建立應用時須要先進入項目目錄。

  • 應用目錄以下:

  • __init__.py: 說明目錄是一個Python模塊。

  • models.py: 寫和數據庫項目的內容, 設計模型類。

  • views.py: 接收請求,進行處理,與M和T進行交互,返回應答。定義處理函數,視圖函數。

    • 定義處理函數,視圖函數---相對於mini-web中的處理函數 def def add_focus(ret): # 1. 獲取股票代碼
  • tests.py: 寫測試代碼的文件。

  • admin.py: 網站後臺管理相關的文件。

##5.3 應用註冊 創建應用和項目之間的聯繫,須要對應用進行註冊,修改settings.py中的INSTALLED_APPS配置項。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'booktest' #加入'booktest', # 進行應用的註冊

]

##5.4 啓動項目

  • 運行開發web服務器命令:python manage.py runserver
  • 使用Django中內置的服務器:python manage.py runserver
    • 複製文件中的http://127.0.0.1:8000/到瀏覽器並打開(或192.168.x.xx:xxxx)
      • 若是是虛擬機中,可能出現:主機沒法訪問虛擬機中運行的Django項目
      • 運行Django的命令,要寫成: python3 manage.py runserver 0.0.0.0:8000 ,重點就是這個0.0.0.0,這樣才能讓外部訪問到
      • 參考連接2
    • 若是出現:Invalid HTTP_HOST header: '192.168.1.111:8000'. You may need to add '192.168.1.111' to ALLOWED_HOSTS
    • 在咱們建立的項目裏修改setting.py文件 ALLOWED_HOSTS = ['*'] #在這裏請求的host添加了*
    • 參考連接3

#6. 模型類 ##6.1 ORM

django中內嵌了ORM框架,ORM框架能夠將類和數據表進行對應起來,只須要經過類和對象就能夠對數據表進行操做。

  • 在Django中主要是 設計類:模型類。
    • 在models.py文件中填寫 ORM另一個做用:根據設計的類生成數據庫中的表。

##6.2 模型類設計 在應用models.py中設計模型類,必須繼承於models.Model類。

  • 1) 設計BookInfo類。
  • 2) 設計HeroInfo類。 Models.ForeignKey能夠創建兩個模型類之間一對多的關係,django在生成表的時候,就會在多端的表中建立一列做爲外鍵,創建兩個表之間一對多的關係。

##6.3 模型類生成表

    1. 生成遷移文件
    • 命令:python manage.py makemigrations 遷移文件是根據模型類生成的。
    1. 執行遷移生成表
    • 命令:python mange.py migrate 根據遷移文件生成表。 生成表名的默認格式: 應用名_模型類名小寫
  • 3)安裝sqliteman:sudo apt-get install sqliteman 安裝失敗,更換源
    • 根據遷移文件生成表,生成表名的默認格式: 應用名_模型類名小寫

##6.4 經過模型類操做數據表

  • 進入項目shell的命令: python manage.py shell 如下爲在相互shell終端中演示的例子:
  • 首先導入模型類:
> from booktest.models import BookInfo,HeroInfo
#1)	向booktest_bookinfo表中插入一條數據。
	b = BookInfo() #定義一個BookInfo類的對象
	b.btitle ='天龍八部' #定義b對象的屬性並賦值
	b.bpub_date = date(1990,10,11) 
	b.save() #纔會將數據保存進數據庫
#2) 查詢出booktest_bookinfo表中id爲1的數據。
	b = BookInfo.objects.get(id=1) 
#3) 在上一步的基礎上改變b對應圖書的出版日期。
	b.bpub_date = date(1989,10,21)
	b.save() #纔會更新表格中的數據
#4) 緊接上一步,刪除b對應的圖書的數據。
	b.delete() #纔會刪除
#5) 向booktest_heroInfo表中插入一條數據。
	h = HeroInfo()
	h.hname = '郭靖'
	h.hgender = False
	h.hcomment = ‘降龍十八掌’
	b2 = BookInfo.objects.get(id=2)
	h.hbook = b2  #給關係屬性賦值,英雄對象所屬的圖書對象
	h.save() 
#6) 查詢圖書表裏面的全部內容。
	BookInfo.objects.all()
	HeroInfo.objects.all()

###6.4.1. models.py中:

from django.db import models
# 設計和表對應的類,模型類
# Create your models here.

# 一類
# 圖書類


class BookInfo(models.Model):   # 要繼承models.Model之後,纔是一個模型類
    # '''圖書模型類'''
    # 圖書名稱,Charfield說明是一個字符串,max_length指定字符串的最大長度
    btitle = models.CharField(max_length=20)
    # 出版日期,DateField說明是一個日期類型
    bpub_date = models.DateField()

# 生成的db.sqlite3能夠用sudo apt-get install sqliteman後,打開

# django默認sqlite小型數據庫,要替換成mysql



# 多類
# 英雄人物類
# 英雄名 name
# 性別 hgender
# 年齡 hage
# 備註 hcomment
# 關係屬性 hbook,創建圖書類和英雄人物類之間的一對多關係
class HeroInfo(models.Model):

    # '''英雄人物模型類'''

    hname = models.CharField(max_length=20)  # 英雄名稱

    # 性別,BooleanField說明是bool類型,default指定默認值,False表明男
    hgender = models.BooleanField(default=False)
    # 備註
    hcomment = models.CharField(max_length=128)
    # 關係屬性 hbook,創建圖書類和英雄人物類之間的一對多關係
    # 關係屬性對應的表的字段名格式: 關係屬性名_id
    hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE,)
    # ForeignKey外鍵

# 經過模型類操做數據表
# 進入項目shell的命令:python manage.py shell
#
# 增長實例屬性要和類屬性名稱同樣

##6.5 關聯操做

###1) 查詢出id爲2的圖書中全部英雄人物的信息。

b = BookInfo.objects.get(id=2)
b.heroinfo_set.all() #查詢出b圖書中全部英雄人物的信息

6.5.1_png

#7. 後臺管理

##1) 本地化

  • 語言和時區的本地化。
  • 修改settings.py文件。
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans' # 使用中文

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai' # 中國時間

##2) 建立管理員

  • 命令:python manage.py createsuperuser
    • 執行時,可能會報錯:Django項目出現: 禁止訪問(403),CSRF驗證失敗,相應中斷
    • 解決辦法:在app的views.py 文件中能夠添加一個 from django.template import RequestContext 而後,渲染函數render 添加便可。
      • 如: return render(request, ‘users/register.html’,context={‘form’:form})
      • 參考連接7.2

##3) 註冊模型類 在應用下的admin.py中註冊模型類,告訴djang框架根據註冊的模型類來生成對應表管理頁面。

from booktest.models import BookInfo, HeroInfo

admin.site.register(BookInfo)
admin.site.register(HeroInfo)
  • __str__:若是一個類中定義了__str__方法,那麼在打印對象時,默認輸出該方法的返回值
    • models.py中:重寫一個__str__方法
class BookInfo(models.Model):
    """圖書模型類"""
    ...  
    def \_\_str__(self):
        # 返回英雄名
        return self.hname

##4) 自定義管理頁面 自定義模型管理類:模型管理類就是告訴django在生成的管理頁面上顯示哪些內容。

class BookInfoAdmin(admin.ModelAdmin):
    """圖書模型管理類"""
    list_display = ['id', 'btitle', 'bpub_date']

class HeroInfoAdmin(admin.ModelAdmin):
    """英雄人物管理類"""
    list_display = ['id', 'hname', 'hcomment']

# 註冊模型類
admin.site.register(BookInfo, BookInfoAdmin)
admin.site.register(HeroInfo, HeroInfoAdmin)

#8. 視圖 在Django中,經過瀏覽器去請求一個頁面時,使用視圖函數來處理這個請求的,視圖函數處理以後,要給瀏覽器返回頁面內容。 ##8.1視圖函數的使用 ###1) 定義視圖函數 視圖函數定義在views.py中。

  • 例:
def index(request):
    #進行處理。。。
    return HttpResponse('hello python')

視圖函數必須有一個參數request,進行處理以後,須要返回一個HttpResponse的類對象,hello python就是返回給瀏覽器顯示的內容。 ###2) 進行url配置---項目文件夾(test1)下的urls.py url配置的目的是讓創建url和視圖函數的對應關係。url配置項定義在urlpatterns的列表中,每個配置項都調用url函數。 url函數有兩個參數,第一個參數是一個正則表達式,第二個是對應的處理動做。

  • 配置url時,有兩種語法格式:
    • a) url(正則表達式,視圖函數名)
    • b) url(正則表達式,include(應用中的urls文件))
  • 工做中在配置url時,首先在項目的urls.py文件中添加配置項,
  • 但並不寫具體的url和視圖函數之間的對應關係,而是寫包含具體應用的urls.py文件,
  • 而後,在應用的urls.py文件中寫url和視圖函數的對應關係。 ##8.2 url匹配的過程 8.2_png 在項目的/test1/urls.py文件中包含具體應用的urls.py文件,應用的/booktest/urls.py文件中寫url和視圖函數的對應關係。
urlpatterns = [
    url(r'^admin/', admin.site.urls), # 配置項目
    url(r'^',include('booktest.urls')), # 包含booktest應用中urls
    # path('admin/', admin.site.urls),
]
  • 可能會報錯:include()函數報錯'provide the namespace argument to include() instead.' % len(arg)
    • 解決方案:url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
    • 參考連接8.2
# 建議直接將項目test1/urls.py文件的內容,直接複製到應用booktest/urls.py文件中,再將不須要的地方修改掉,這樣就不會錯了。

"""test/urls.py"""
from django.conf.urls import url, include
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
]
# ---------------------------------------------------------------------------------
"""booktest/urls.py"""
from django.conf.urls import url
from booktest import views


# 建立列表urlpatterns,視圖調用就是從這個列表中調用,
# 須要經過導入from django.conf.urls import url 來調用項目的urls文件
# 在應用的urls文件中進行url配置的時候:
# 1.嚴格匹配開頭和結尾
urlpatterns = [
    # 經過url函數設置url路由配置項
    url(r'^index$', views.index),    # 寫入對應的index名字,創建/index和視圖index之間的關係
    # url(r'^index2', views.index2),  # 此時的輸入仍是「老鐵,沒毛病」不對,由於在上一項匹配成功後,就再也不匹配下一項了
    url(r'^index2$', views.index2),   # 故,爲了解決這個問題,需嚴格匹配開頭和結尾,加上^與$
    url(r'^books$', views.show_books), # 顯示圖書信息,即/boos頁面顯示的內容
    url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組()
]

8.2.1. 當用戶輸入如http://127.0.0.1:8000/aindex時,去除域名和最前面的/,剩下aindex,拿aindex字符串

8.2.2. 先到項目的urls文件中進行匹配,配置成功後,去除匹配的a字符,拿剩下的index字符串繼續到項目的urls

8.2.3. 文件中進行正則匹配,匹配成功以後執行視圖函數index,index視圖函數返回內容hello python給瀏覽器顯示

#9. 模板 模板不只僅是一個html文件。 ##9.1 模板文件的使用

  • 1 建立模板文件夾:項目test1/下面建立templates文件夾---/test1/templates/
  • 2 配置模板目錄
    • settings.py文件中有TEMPLATES 選項,這個配置就是讓咱們去設置模板目錄的。
    • 在'DIRS': []中設置模板文件的目錄,設置路徑,可是路徑不能隨便設置,而應該根據BASE_DIR來設置
    • 項目目錄的絕對路徑,pwd,/home/huang/bj18/test1獲得的就是項目目錄
    • 設置時,將BASE_DIR和模板目錄進行拼接
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # 設置模板文件目錄,路徑
        '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',
            ],
        },
    },
]
  • 設置完模板目錄後,便可使用,爲了給多個應用(booktest等)使用,不混淆,會在模板文件夾(templates)下,再新建同名文件夾booktest,

  • 新建模板文件index.html,寫好內容後,便可使用模板文件;

  • 在mini_frame框架中,手動打開一個文件讀取出來,Django中不能這樣作,使用模板文件應該遵循如下步驟:

  • 3 使用模板文件

    • 1.定義視圖函數,HttpRequest
      • 在booktest下新建一個urls.py
      • 視圖函數的做用是: 調用模板,處理數據並返回給瀏覽器。
      • 若是須要操做數據庫,須要和M、T進行交互
    • 2.進行url配置,創建url地址和視圖的對應關係,和Flask類似
      • 瀏覽器中輸入http:127.0.0.1:8000/index # 用戶要顯示該url,須要在應用app中的urls列表中,添加該url
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader, RequestContext
from booktest.models import BookInfo, HeroInfo    # 導入模型類


def index(request):
    ···
    return render(request, 'booktest/index.html',
                  {'content': 'hello world', 'list':list(range(1, 10))}, )
urlpatterns = [
        url(r'^index$', views.index),    # 寫入對應的index名字,創建/index和視圖index之間的關係
]

如下a)-c)爲視圖函數調用模板文件的分析過程,可省略:
- 發現除get_template('booktest/index.html')中的'booktest/index.html'、context中的字典不一樣外,其他的部分都相同,
- 故,從新定義一個函數my_render(),但此方法是多餘的,由於已經導入了render,因此能夠直接使用
```
def my_render(request, template_path, context_dict):
    """使用模板文件"""
    # 直接將index中的模板文件拿過來使用
    # 1.加載模板文件
    temp = loader.get_template(template_path)  # 寫上目錄,該目錄是相對templetes的目錄---改成template_path
    # 2.定義模板文件上下文:給模板文件傳遞數據,request,和要傳遞的數據,經過{}的鍵值對來傳減去
    # 導入from django.template import loader, RequestContext
    # context = RequestContext(request, {''})   # Django1.11之後,就是直接傳入{}便可,再也不傳入RequestContext(request, {''})---{}字典也改成經過context_dict來改變
    # context = {}
    context = context_dict
    # 3.模板渲染(目的是把使用的變量,還有一些語句給替換掉):產生標準的html內容,temp中有一個render方法,將context放進去
    res_html = temp.render(context)
    # 4.返回給瀏覽器
    return HttpResponse(res_html)
```
    - a)加載模板文件----views.py中,使用模板文件 # 1.加載模板文件
        - 導入包 from django.template import loader
        - temp = loader.get_template('booktest/index.html')  # 寫上目錄,該目錄是相對templetes的目錄
    - b) 定義目標上下文---給模板文件傳遞定義的變量的值
        - 給**模板文件傳遞數據**:request和要傳遞的數據,經過{}的鍵值對來傳進去
            - 導入from django.template import loader, RequestContext
            - context = RequestContext(request, {''})   # Django1.11之後,就是直接傳入{}便可,再也不傳入RequestContext(request, {''})
            - \# context = {}
    - c) 模板渲染(目的是把使用的變量,還有一些語句給替換掉):產生標準的html內容,temp中有一個render方法,將context放進去
        - res_html = temp.render(context)
    - d) 返回給瀏覽器
        - return HttpResponse(res_html)

9.2 給模板文件傳遞數據

  • 模板變量使用:{{ 模板變量名 }}
  • 模板代碼段:{%代碼段%}
  • for循環:
{% for i in list %}
	list不爲空時執行的邏輯
{% empty %}
	list爲空時執行的邏輯
{% endfor %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板文件</title>
    <style type="text/css">
    </style>
</head>
<body>
<h1>這是一個模板文件</h1>
使用模板變量:<br/>
{{ content }}<br/>
使用列表:<br/>
{{ list }}<br/> # 這是直接顯示列表的內容,py中還能夠遍歷出列表中的每個文件
for循環:<br/>
<ul>
    {% for i in list %}
        <li>{{ i }}</li>
    {% endfor %}
</ul>
</body>
</html>

#9.3:小結:

  • 咱們須要作的事情:
    • 1)定義視圖函數
      • 視圖函數定義在views.py中。
    • 2)進行url配置,項目視圖+應用視圖,兩個。
      • """test/urls.py"""
      • """booktest/urls.py"""

#10. 案例完成 編碼以前的準備工做:

  • 1 設計出訪問頁面的url和對應的視圖函數的名字,肯定視圖函數的功能。

    • def show_books()、detail()
  • 2 設計模板文件的名字。

    • area.html、index.html

    如下爲案例中的簡單設計過程:

  • 1 完成圖書信息的展現:

    • 1.1 設計url,經過瀏覽器訪問 http://127.0.0.1:8000/books 時顯示圖書信息頁面。
      # /test1/urls.py:
      urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
      ]
      #/booktest/urls.py:
      urlpatterns = [
          # 經過url函數設置url路由配置項
          url(r'^index$', views.index),
          url(r'^books$', views.show_books), # 顯示圖書信息,即/books頁面顯示的內容
          url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組()
      ]
  • 1.2 設計url對應的視圖函數show_books。

    • 查詢出全部圖書的信息,將這些信息傳遞給模板文件。
      # views.py:
      import sys
      from django.shortcuts import render
      from django.http import HttpResponse
      from django.template import loader,
      from booktest.models import BookInfo, HeroInfo    # 導入模型類
      
      
      def show_books(request):
          """顯示圖書的信息"""
          # 1. 經過M查找圖書表中的數據
          books = BookInfo.objects.all()
          # 2. 使用模板
          return render(request, 'booktest/show_books.html', {'books': books})
  • 1.3 編寫模板文件show_books.html。

    • 遍歷顯示出每一本圖書的信息。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>顯示圖書信息</title>
    <style type="text/css">
    </style>
</head>
<body>
圖書信息以下:
    {% for book in books %}
        <li><a href="/books/{{ book.id }}">{{ book.btitle}}</a></li>
    {% endfor %}
</body>
</html>
  • 2 完成點擊某本圖書時,顯示出圖書裏全部英雄信息的頁面。
    • 2.1 設計url,經過訪問http://127.0.0.1:8000/books/數字時顯示對應的英雄信息頁面。
      • 這裏數字指點擊的圖書的id。
        url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組()
    • 2.2 設計對應的視圖函數detail。
      • 接收圖書的id,根據id查詢出相應的圖書信息,而後查詢出圖書中的全部英雄信息。
        def detail(request, bid):
            '''查詢圖書關聯英雄信息'''
            # 1. 根據bid查詢圖書信息
            book = BookInfo.objects.get(id=bid)
            # 2. 查詢和book關聯的信息---要分析1對多(由1查多b.heroinfo_set.all())仍是多對1(h.hbook)
            # HeroInfo.objects.fliter(hbook__id=1)
            heros = book.heroinfo_set.all()
            # 須要顯示圖書的名字,和關聯的英雄名字和備註
            # 3. 使用模板detail,建立templates/bootest/detail.html
            return render(request, 'booktest/detail.html', {'book': book, 'heros': heros})  # 注意,此處是heros,不是hero,否則圖書信息就沒法顯示
            # 去應用booktest/urls中設置地址。
    • 2.3 編寫模板文件detail.html:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>顯示圖書關聯的英雄信息</title>
        <style type="text/css">    
        </style>
    </head>
    <body>
    <h1>{{ book.btitle }}</h1>
    英雄信息以下:<br/>
    <ul>
        {% for hero in heros %}
            <li>{{ hero.hname }}--{{ hero.hcomment }}</li>
        {% empty %}
            <li>沒有英雄信息</li>
        {% endfor %}
    </ul>
    
    </body>
    </html>
相關文章
相關標籤/搜索