Python_Django_入門

Python下有許多款不同的 Web 框架。Django是重量級選手中最有代表性的一位。許多成功的網站和APP都基於Django。

Django是一個開放源代碼的Web應用框架,由Python寫成。

Django遵守BSD版權,初次發佈於2005年7月, 並於2008年9月發佈了第一個正式版本1.0 。

Django採用了MVC的軟件設計模式,即模型M,視圖V和控制器C。

 


輕量級框架側重於減小開發的複雜度,相應的它的處理能力便有所減弱(如事務功能弱、不具備分佈式處理能力),比較適用於開發中小型企業應用。採用輕量框架一方面因爲儘可能的採用基於POJOs的方法進行開發,使應用不依賴於任何容器,這可以提高開發調試效率;另一方面輕量級框架多數是開源項目,開源社區提供了良好的設計和許多快速構建工具以及大量現成可供參考的開源代碼,這有利於項目的快速開發。

重量級的框架的優點是開發簡單,你要做的都幫你做了,

輕量級框架的優點則是學習成本低,運行效率相對來說會高

輕量級框架的產生並非是對重量級框架的否定,甚至在某種程度上可以說二者是互補的。輕量級框架在努力發展以開發具有更強大,功能更完備的企業應用;

 

Django流程介紹

 

MVC 編程模式_百度百科     

  • Model(模型)表示應用程序核心(比如數據庫記錄列表)。

  • View(視圖)顯示數據(數據庫記錄)。

  • Controller(控制器)處理輸入(寫入數據庫記錄)。

MVC 模式同時提供了對 HTML、CSS 和 JavaScript 的完全控制。

Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。
  通常模型對象負責在數據庫中存取數據。

View(視圖)是應用程序中處理數據顯示的部分。
  通常視圖是依據模型數據創建的。

Controller(控制器)是應用程序中處理用戶交互的部分。
  通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。

MVC 分層有助於管理複雜的應用程序,因爲您可以在一個時間內專門關注一個方面。例如,您可以在不依賴業務邏輯的情況下專注於視圖設計。同時也讓應用程序的測試更加容易。

MVC 分層同時也簡化了分組開發。不同的開發人員可同時開發視圖、控制器邏輯和業務邏輯。


Django Start

官方安裝文檔

https://docs.djangoproject.com/zh-hans/2.1/intro/install/

pip3 install django

>>> import django
>>> print(django.get_version())
2.1

 

創建django項目 ,我這裏使用的是pycharm

 

 

創建好的目錄結構如下

 

 

 

 

 

創建APP

在Django項目中可以包含多個APP,相當於一個大型項目中的分系統、子模塊、功能部件等,相互之間比較獨立,但也有聯繫,所有APP共享項目資源

輸入:python manage.py startapp myapp
生成myapp文件夾

 

視圖和url配置

myapp/views.py文件代碼:

# Create your views here.
from django.http import HttpResponse         #需要導入HttpResponse模塊



def hello(request):                          #request參數必須有,名字類似self的默認規則,可以修改,它封裝了用戶請求的所有內容
    return HttpResponse("Hello world ! ")    #不能直接字符串,必須是由這個類封裝,此爲Django規則

 

DjangoDemo/urls.py文件代碼:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', views.hello),
]

啓動項目

 

 

訪問

 

 

 

 

文件詳解

urls.py

配置路由,一個請求對應一個方法

Example

Here’s a sample URLconf:

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

 

 

要從URL捕獲值,只需在其周圍加上括號。不需要添加前導斜槓,因爲每個URL都有。

For example, it’s ^articles, not ^/articles.

每個正則表達式字符串前面的“r”是可選的,但建議使用。它告訴python一個字符串是“原始的”——字符串中的任何內容都不應該被轉義。

Example requests:

A request to /articles/2005/03/ would match the third entry in the list. Django would call the functionviews.month_archive(request, '2005', '03').
/articles/2005/3/ would not match any URL patterns, because the third entry in the list requires two digits for the month.
/articles/2003/ would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the function views.special_case_2003(request)
/articles/2003 would not match any of these patterns, because each pattern requires that the URL end with a slash.
/articles/2003/03/03/ would match the final pattern. Django would call the functionviews.article_detail(request, '2003', '03', '03').

 

Named groups

上面的示例使用簡單的、非命名的正則表達式組(通過括號)來捕獲URL的位,並將其作爲位置參數傳遞給視圖。在更高級的用法中,可以使用命名的正則表達式組捕獲URL位並將其作爲關鍵字參數傳遞給視圖。


在Python正則表達式中,命名正則表達式組的語法是(?p<name>pattern),其中name是組的名稱,pattern是一些要匹配的模式。


下面是上面的示例urlconf,重寫爲使用命名組:

from django.conf.urls import url
 
from . import views
 
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments. For example:

  • A request to /articles/2005/03/ would call the function views.month_archive(request, year='2005',month='03'), instead of views.month_archive(request, '2005', '03').
  • A request to /articles/2003/03/03/ would call the function views.article_detail(request, year='2003',month='03', day='03').

In practice, this means your URLconfs are slightly more explicit and less prone to argument-order bugs – and you can reorder the arguments in your views’ function definitions. Of course, these benefits come at the cost of brevity; some developers find the named-group syntax ugly and too verbose.

 

What the URLconf searches against

The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name.

例如,在一個請求:

https://www.example.com/myapp/

在請求中 https://www.example.com/myapp/?page=3 這個請求將被我們當成同上一個請求,這就是URLconf不看請求的方法。在其他的話,所有的請求的方法—郵件頭,get,等。routed——將兩個相同的功能,在相同的URL。

Captured arguments are always strings

每個捕獲的參數都作爲一個普通的python字符串發送到視圖中,而不管正則表達式是什麼類型的匹配。例如,在此urlconf行中:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

the year argument passed to views.year_archive() will be a string,

not an integer, even though the [0-9]{4} will only match integer strings.

 

wsgi

框架,即framework,特指爲解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統,簡單地說,就是你用別人搭建好的舞臺來做表演。

web應用的流程:

1.瀏覽器發送一個HTTP請求;

2.服務器收到請求,生成一個HTML文檔;

3.服務器把HTML文檔作爲HTTP響應的Body發送給瀏覽器;

4.瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。

對於所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。

最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。

    如果要動態生成HTML,就需要把上述步驟自己來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,如果我們自己來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。

    正確的做法是底層代碼由專門的服務器軟件實現,我們用Python專注於生成HTML文檔。因爲我們不希望接觸到TCP連接、HTTP原始請求和響應格式,所以,需要一個統一的接口,讓我們專心用Python編寫Web業務。

    這個接口就是WSGI:Web Server Gateway Interface。

詳細瞭解請看文章 https://www.cnblogs.com/hujq1029/p/6098300.html

 

 

app/Django Views

最簡單的返回一個字符串形式的view

from django.http import HttpResponse
 
def my_view(request):
    if request.method == 'GET':
        # <view logic>
        return HttpResponse('result')

 

如果想直接返回一個html文檔

from django.shortcuts import render,HttpResponse
 
# Create your views here.
 
 
def test_view(request):
    return render(request,'index.html')

 

html文件默認需要放在template目錄下,其它配置需要修改setting文件

Django Models  

django 本身提供了非常強大易使用的ORM組件,並且支持多種數據庫,如sqllite,mysql,progressSql,Oracle等,當然最常用的搭配還是mysql,要啓用orm,先要配置好連接數據 的信息

在你創建的project目錄下編輯settings.py 

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'OldboyWebsite', #確保此數據庫已存在
        'HOST':'',
        'PORT':'',
        'USER':'root',
        'PASSWORD':''
    }
}

下面要開始學習建表Django ORM語法了,爲了更好的理解,我們來做一個基本的 書籍/作者/出版商 數據庫結構。 我們這樣做是因爲 這是一個衆所周知的例子,很多SQL有關的書籍也常用這個舉例。

我們來假定下面的這些概念、字段和關係:

  • 一個作者有姓,有名及email地址。

  • 出版商有名稱,地址,所在城市、省,國家,網站。

  • 書籍有書名和出版日期。 它有一個或多個作者(和作者是多對多的關聯關係[many-to-many]), 只有一個出版商(和出版商是一對多的關聯關係[one-to-many],也被稱作外鍵[foreign key])

from django.db import models

# Create your models here.



class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()


class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()


class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE,)
    publication_date = models.DateField()

更多models field 字段:https://docs.djangoproject.com/en/1.9/ref/models/fields/ 

每個模型相當於單個數據庫表,每個屬性也是這個表中的一個字段。 屬性名就是字段名,它的類型(例如CharField )相當於數據庫的字段類型 (例如 varchar )。例如, Publisher 模塊等同於下面這張表(用PostgreSQL的 CREATE TABLE 語法描述):

更多models field 字段:https://docs.djangoproject.com/en/1.9/ref/models/fields/ 

每個模型相當於單個數據庫表,每個屬性也是這個表中的一個字段。 屬性名就是字段名,它的類型(例如CharField )相當於數據庫的字段類型 (例如 varchar )。例如, Publisher 模塊等同於下面這張表(用PostgreSQL的 CREATE TABLE 語法描述):

模型安裝

完成這些代碼之後,現在讓我們來在數據庫中創建這些表。 要完成該項工作,第一步是在 Django 項目中 激活這些模型。 將上面的模型所在的app (此例子app是myapp) 添加到配置文件的已安裝應用列表中即可完成此步驟。

再次編輯 settings.py 文件, 找到 INSTALLED_APPS 設置。 INSTALLED_APPS 告訴 Django 項目哪些 app 處於激活狀態。 缺省情況下如下所示:

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

使數據庫按照模型的配置生成表結構

 python manage.py makemigrations  #生成同步紀錄

異常一

No module named 'MySQLdb'

原因:python3連接MySQL不能再使用mysqldb,取而代之的是pymysql。

解決方法:在python的MySQL包中,即路徑:C:\Users\adong\AppData\Local\Programs\Python\Python36\Lib\site-packages\Django-2.0.3-py3.6.egg\django\db\backends\mysql

下的主包的__init__.py文件中加入:

import pymysql

pymysql.install_as_MySQLdb()

 

異常二

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

解決方法:在python的MySQL包中,即路徑:C:\Users\adong\AppData\Local\Programs\Python\Python36\Lib\site-packages\Django-2.0.3-py3.6.egg\django\db\backends\mysql

下的 base.py 文件中,註釋掉一下兩行代碼:

if version < (1, 3, 3):
     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__) 

 

 

Django Template

你可能已經注意到我們在例子視圖中返回文本的方式有點特別。 也就是說,HTML被直接硬編碼在 Python 代碼之中。

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

儘管這種技術便於解釋視圖是如何工作的,但直接將HTML硬編碼到你的視圖裏卻並不是一個好主意。 讓我們來看一下爲什麼:

  • 對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改往往比底層 Python 代碼的修改要頻繁得多,因此如果可以在不進行 Python 代碼修改的情況下變更設計,那將會方便得多。

  • Python 代碼編寫和 HTML 設計是兩項不同的工作,大多數專業的網站開發環境都將他們分配給不同的人員(甚至不同部門)來完成。 設計者和HTML/CSS的編碼人員不應該被要求去編輯Python的代碼來完成他們的工作。

  • 程序員編寫 Python代碼和設計人員製作模板兩項工作同時進行的效率是最高的,遠勝於讓一個人等待另一個人完成對某個既包含 Python又包含 HTML 的文件的編輯工作。

 

基於這些原因,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 我們可以使用 Django的 模板系統 (Template System)來實現這種模式,這就是本章要具體討論的問題。

 

Django 模版基本語法

>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
u'My name is Stephane.'

同一模板,多個上下文

一旦有了 模板 對象,你就可以通過它渲染多個context, 例如:

>>> from django.template import Template, Context
>>> t = Template('Hello, {{ name }}')
>>> print t.render(Context({'name': 'John'}))
Hello, John
>>> print t.render(Context({'name': 'Julie'}))
Hello, Julie
>>> print t.render(Context({'name': 'Pat'}))
Hello, Pat

 

無論何時我們都可以像這樣使用同一模板源渲染多個context,只進行 一次模板創建然後多次調用render()方法渲染會更爲高效:

# Bad
for name in ('John', 'Julie', 'Pat'):
    t = Template('Hello, {{ name }}')
    print t.render(Context({'name': name}))
 
# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
    print t.render(Context({'name': name}))

Django 模板解析非常快捷。 大部分的解析工作都是在後臺通過對簡短正則表達式一次性調用來完成。 這和基於 XML 的模板引擎形成鮮明對比,那些引擎承擔了 XML 解析器的開銷,且往往比 Django 模板渲染引擎要慢上幾個數量級。

深度變量的查找

在到目前爲止的例子中,我們通過 context 傳遞的簡單參數值主要是字符串,然而,模板系統能夠非常簡潔地處理更加複雜的數據結構,例如list、dictionary和自定義的對象。

在 Django 模板中遍歷複雜數據結構的關鍵是句點字符 (.)。

最好是用幾個例子來說明一下。 比如,假設你要向模板傳遞一個 Python 字典。 要通過字典鍵訪問該字典的值,可使用一個句點:

>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'Sally is 43 years old.'

同樣,也可以通過句點來訪問對象的屬性。 比方說, Python 的 datetime.date 對象有 year 、 month 和 day 幾個屬性,你同樣可以在模板中使用句點來訪問這些屬性:

>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
u'The month is 5 and the year is 1993.'

這個例子使用了一個自定義的類,演示了通過實例變量加一點(dots)來訪問它的屬性,這個方法適用於任意的對象。

>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
u'Hello, John Smith.'

點語法也可以用來引用對象的* 方法*。 例如,每個 Python 字符串都有 upper() 和 isdigit() 方法,你在模板中可以使用同樣的句點語法來調用它們:

>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
u'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
u'123 -- 123 -- True'

注意這裏調用方法時並* 沒有* 使用圓括號 而且也無法給該方法傳遞參數;你只能調用不需參數的方法

最後,句點也可用於訪問列表索引,例如:

>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
u'Item 2 is carrots.'

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章