python_Django之模板模型

主要文件

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、做網(wǎng)站、四方臺網(wǎng)絡(luò)推廣、小程序開發(fā)、四方臺網(wǎng)絡(luò)營銷、四方臺企業(yè)策劃、四方臺品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供四方臺建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:muchs.cn

manage.py      創(chuàng)建服務(wù)器

settings.py    項(xiàng)目的配置信息

urls.py         URL分發(fā)器(URLconf----URL和函數(shù)的映射表)

view.py         視圖(函數(shù))


manage.py  

啟動manage.py創(chuàng)建簡單的服務(wù)器,用于調(diào)測

python manage.py runserver 0.0.0.0:8000

urls.py

patterns:第一個是空字符串(后面會解釋)

include:

 urls

from django.conf.urls.defaults import patterns, include, url
from mysite.views import hello      # 通常是導(dǎo)*  views. 調(diào)用
urlpatterns = patterns('',
    url(r'^hello/$', hello),
    )

如果有人申請?jiān)L問/hello(尾部沒有斜杠/)會怎樣。 因?yàn)槲覀兊腢RL模式要求尾部有一個斜杠(/),那個申請URL將不匹配。 然而,默認(rèn)地,任何不匹配或尾部沒有斜杠(/)的申請URL,將被重定向至尾部包含斜杠的相同字眼的URL。 (這是受配置文件setting中APPEND_SLASH項(xiàng)控制的

 url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

       這三個括號里的內(nèi)容會以第二第三第四的參數(shù)傳給 函數(shù),第一參是request

view.py

一個視圖就是Python的一個函數(shù)。這個函數(shù)第一個參數(shù)的類型是HttpRequest;它返回一個HttpResponse實(shí)例。

request 是一個觸發(fā)這個視圖、包含當(dāng)前Web請求信息的對象,是類django.http.HttpRequest的一個實(shí)例。

from django.http import HttpResponse
def hello(request):
    return HttpResponse("Hello world")    # 直接返回字符串
---------------------------------------------------------------------
from django.shortcuts import render
def be_001(request):
    return render(request,'001.html')    # 返回template文件下的001.html

settings.py

設(shè)置指定URLconf  (url分發(fā)器)

ROOT_URLCONF = 'mysite.urls'     # 即mysite/urls.py

  1. 進(jìn)來的請求轉(zhuǎn)入/hello/.

  1. Django通過在ROOT_URLCONF配置來決定根URLconf.

  1. Django在URLconf中的所有URL模式中,查找第一個匹配/hello/的條目。

  1. 如果找到匹配,將調(diào)用相應(yīng)的視圖函數(shù),并把HttpRequest 對象作為第一個參數(shù)

  1. 視圖函數(shù)返回一個HttpResponse

  1. Django轉(zhuǎn)換HttpResponse為一個適合的HTTP response, 以Web page顯示出來

指定模板路徑

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
    
    # 自動獲取settings.py的路徑,并拼接得到模板路徑
)
# 單元素元組中必須使用逗號,以此消除與圓括號表達(dá)式之間的歧義。




模板

在project目錄 (django-admin.py startproject)中  輸入命令 python manage.py shell啟動交互界面(會自動加載相關(guān)配置)

循環(huán)判斷

{% for item in item_list %}     # 表示當(dāng)前循環(huán)的執(zhí)行次數(shù)的整數(shù)計(jì)數(shù)器。 這個計(jì)數(shù)器是從1開始的, forloop.counter0從零開始

<p>` forloop`.`counter `: ` item `</p>   # forloop.revcounter 是表示循環(huán)中剩余項(xiàng)的整型變量,forloop.revcounter0

{% endfor %}      #forloop.first 是一個布爾值,如果該迭代是第一次執(zhí)行,那么它被置為true,forloop.last

 #  forloop.parentloop 是一個指向當(dāng)前循環(huán)的上一級循環(huán)的 forloop 對象的引用(在嵌套循環(huán)的情況下)                            

{% if ordered_warranty %}         # 只能用一種邏輯操作符 and 或 or ,兩個一起用不可以的

{% else %}

{% endif %}


{% ifequal user currentuser %}      # 判斷 user currentuser 是否相等,字符串要“”,只能判斷兩個變量是否相等
   <h2>Welcome</h2>                
# 不能用于判斷變量是否等于什么,True {op:123} [1,2,3]等等
{% endifequal %}


變量賦值

{{ person_name }}   稱為 變量(variable) 。這意味著在此處插入指定變量的值。

>>> from django import template                # Template 可用render方法傳 Context 參數(shù)
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)                    # 返回的是Unicode r''
My name is Fred.

Django模板系統(tǒng)的基本規(guī)則: 寫模板,創(chuàng)建 Template 對象,創(chuàng)建 Context , 調(diào)用 render() 方法。

>>> from django.template import Template, Context
>>> import datetime
>>> 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.'
>>> d = datetime.date(1993, 5, 2)        #時間也可以這么用 
>>> d.year
1993
>>> t = Template('Item 2 is {{ items.2 }}.')            # 列表索引(不能用負(fù)數(shù))
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})

#調(diào)用方法時并沒有使用圓括號 而且也無法給該方法傳遞參數(shù);
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')    # var變量,調(diào)用upper和isdigit方法
>>> t.render(Context({'var': 'hello'}))
u'hello -- HELLO -- False'

  • 字典類型查找 (比如 foo["bar"] )

  • 屬性查找 (比如 foo.bar )

  • 方法調(diào)用 (比如 foo.bar() )

  • 列表類型索引查找 (比如 foo[bar] )

 系統(tǒng)使用找到的第一個有效類型。 這是一種短路邏輯。

 一個變量不存在,模板系統(tǒng)會把它展示為空字符串,不做任何事情來表示失敗。

方法調(diào)用

拋異常

在方法查找過程中,如果某方法拋出一個異常的話它將被傳播(報錯)。

若該異常有一個 silent_variable_failure 屬性并且值為True ,模板里的指定變量會被置為空字符串(不報錯)

模版中避免關(guān)鍵函數(shù)的誤操作

def delete(self):

# Delete the account

delete.alters_data = True

# 把delete看成一個對象,設(shè)置它的alters_data屬性。這樣在渲染的時候,就會變成failed silent。不會執(zhí)行

注釋

單行

{# This is a comment #}

多行

{% comment %}
This is a
multi-line comment.
{% endcomment %}

過濾器

常用的幾個

模板過濾器是在變量被顯示前修改它的值的一個簡單方法。

{{ my_list|first|upper }}
{{ bio|truncatewords:"30" }}

addslashes : 添加反斜杠到任何反斜杠、單引號或者雙引號前面。 這在處理包含JavaScript的文本時是非常有用的。

date : 按指定的格式字符串參數(shù)格式化 date 或者 datetime 對象, 范例:

{{ pub_date|date:"F j, Y" }}

格式參數(shù)的定義在附錄F中。

length : 返回變量的長度。 對于列表,這個參數(shù)將返回列表元素的個數(shù)。 對于字符串,這個參數(shù)將返回字符串中字符的個數(shù)。 你可以對列表或者字符串,或者任何知道怎么測定長度的Python 對象使用這個方法(也就是說,有 __len__() 方法的對象)

詳細(xì) https://www.douban.com/note/145065606/

模板加載

settings.py

import os.path

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)

在視圖中

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)

更為簡潔的視圖

from django.shortcuts import render_to_response
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('current_datetime.html', {'current_date': now})
    # 返回HttpResponse 對象;
    # 第一個參數(shù)必須是要使用的模板名稱;
    # 第二個參數(shù),那么該參數(shù)必須是為該模板創(chuàng)建 Context 時所使用的字典,默認(rèn)是空字典

locals() 技巧

def current_datetime(request):
    now = datetime.datetime.now()        # 多余的變量名...
    return render_to_response('current_datetime.html', {'current_date': now})
def current_datetime(request):       
    current_date = datetime.datetime.now()        # 這個變量名和模板中的一致
    return render_to_response('current_datetime.html', locals())
         # locals()囊括了函數(shù)執(zhí)行到該時間點(diǎn)時所定義的一切變量。

get_template()-模板子目錄

t = get_template('dateapp/current_datetime.html')
return render_to_response('dateapp/current_datetime.html', {'current_date': now})

include 模板標(biāo)簽(笨笨的嵌套網(wǎng)頁)

{% include template_name %}

如果{% include %}標(biāo)簽指定的模板沒找到,Django將會在下面兩個處理方法中選擇一個:

如果 DEBUG 設(shè)置為 True ,你將會在 Django 錯誤信息頁面看到 TemplateDoesNotExist 異常。

如果 DEBUG 設(shè)置為 False ,該標(biāo)簽不會引發(fā)錯誤信息,在標(biāo)簽位置不顯示任何東西。

模板繼承(更加優(yōu)雅的策略)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">        # base.html
<html lang="en">                                     
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h2>My helpful timestamp site</h2>
</body>
</html
{% extends "base.html" %}                        # 繼承模板,替換同名block即可

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

要點(diǎn):

基礎(chǔ)模板中的 {% block %} 標(biāo)簽越多越好。

子模板不必定義父模板中所有的代碼塊。

不允許在同一個模板中定義多個同名的 {% block %} 。





模型

為了提供方便的數(shù)據(jù)訪問API, Django需要以 某種方式 知道數(shù)據(jù)庫層內(nèi)部信息,有兩種實(shí)現(xiàn)方式。 

第一種方式是用Python明確地定義數(shù)據(jù)模型

第二種方式是通過自省來自動偵測識別數(shù)據(jù)模型。

(自?。ㄟ\(yùn)行時自動識別數(shù)據(jù)庫)會導(dǎo)致過載和有數(shù)據(jù)完整性問題。)

笨方法數(shù)據(jù)庫查詢

from django.shortcuts import render_to_response        # 重復(fù)同樣的代碼
import MySQLdb                                         # 綁定死了MySQL 

def book_list(request):
    db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
    cursor = db.cursor()
    cursor.execute('SELECT name FROM books ORDER BY name')
    names = [row[0] for row in cursor.fetchall()]
    db.close()
    return render_to_response('book_list.html', {'names': names})

Django數(shù)據(jù)庫層

from django.shortcuts import render_to_response        # 由Django數(shù)據(jù)庫層來處理
from mysite.books.models import Book                   # 底層數(shù)據(jù)庫代碼更為優(yōu)化,數(shù)據(jù)庫選擇更靈活                
def book_list(request):
    books = Book.objects.order_by('name')
    return render_to_response('book_list.html', {'books': books})

settings.py 中數(shù)據(jù)庫的設(shè)置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }}

MVC 模式

控制器(controller) ---->>>   模型(model) ---->>>   視圖(view)

MTV

" C 由框架自行處理(URLconf)"   ---->>>   模型(Model)---->>> 視圖(Views)---->>> 模板(Template)

APP

理一理project和app:一個project包含多個app,為app提供相關(guān)配置,但model必須在各自的app中

python manage.py startapp books    # 創(chuàng)建APP

在models.py中描述數(shù)據(jù)庫

from django.db import models

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)
    publication_date = models.DateField()

與下面的sql效果一樣

CREATE TABLE "books_publisher" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(30) NOT NULL,
    "address" varchar(50) NOT NULL,
    "city" varchar(60) NOT NULL,
    "state_province" varchar(30) NOT NULL,
    "country" varchar(50) NOT NULL,
    "website" varchar(200) NOT NULL
);

 settings.py 激活app

MIDDLEWARE_CLASSES = (                                        # 注釋部分后續(xù)解釋
    # 'django.middleware.common.CommonMiddleware',
    # 'django.contrib.sessions.middleware.SessionMiddleware',
    # 'django.contrib.auth.middleware.AuthenticationMiddleware',
)

INSTALLED_APPS = (
    # 'django.contrib.auth',
    # 'django.contrib.contenttypes',
    # 'django.contrib.sessions',
    # 'django.contrib.sites',
    'mysite.books',                        
)

檢查上面模型的語法和邏輯(正常返 0 erros found)

python manage.py validate

生成 CREATE TABLE 語句

python manage.py sqlall books

提交到數(shù)據(jù)庫客戶端執(zhí)行

python manage.py syncdb        # 此命令不能用做修改刪除

基本數(shù)據(jù)訪問

python manage.py shell

>>> from books.models import Publisher            # 導(dǎo)入Publisher模型類,與數(shù)據(jù)表進(jìn)行交互
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
...     city='Berkeley', state_province='CA', country='U.S.A.',
...     website='http://www.apress.com/')
>>> p1.save()
>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
...     city='Cambridge', state_province='MA', country='U.S.A.',
...     website='http://www.oreilly.com/')
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]

下面不需要save,直接完成對象的創(chuàng)建與存儲至數(shù)據(jù)庫

>>> p1 = Publisher.objects.create(name='Apress',
...     address='2855 Telegraph Avenue',
...     city='Berkeley', state_province='CA', country='U.S.A.',
...     website='http://www.apress.com/')

重寫__unicode__,方便

class Author(models.Model):
    **def __unicode__(self):**        # __unicode__() 方法可以進(jìn)行任何處理來返回對一個對象的字符串表示
        **return u'%s %s' % (self.first_name, self.last_name)**    # 必須返回Unicode,數(shù)字什么的會報錯

插入更新

>>> p = Publisher(name='Apress',
...         address='2855 Telegraph Ave.',
...         city='Berkeley',
...         state_province='CA',
...         country='U.S.A.',
...         website='http://www.apress.com/')
>>> p.save()        #相當(dāng)于執(zhí)行INSERT INTO books_publisher***  會把主鍵賦值給實(shí)例對象 p
>>> p.id
52    # this will differ based on your own data
>>> p.name = 'Apress Publishing'        # 根據(jù)這個對象可更新數(shù)據(jù)
>>> p.save()                            # 并不是只更新修改過的那個字段,所有的字段都會被更新。
                                        # 部分更新后面再說

查詢

>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]

數(shù)據(jù)過濾(filter--返回列表)

>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: Apress>]

多個參數(shù)會被轉(zhuǎn)換成 AND SQL從句, 因此上面的代碼可以轉(zhuǎn)化成這樣:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher  
WHERE country = 'U.S.A.'
AND state_province = 'CA';
>>> Publisher.objects.filter(name__contains="press")    # 在 name 和 contains 之間有雙下劃線
[<Publisher: Apress>]                                   # 這里,contains部分會被Django翻譯成LIKE語句:
         
注意,SQL缺省的 = 操作符是精確匹配的, 其他類型的查找也可以使用
WHERE name LIKE '%press%';

獲取單個對象

>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>

MultipleObjectsReturned  # 結(jié)果是多個對象,拋出異常
DoesNotExist   #  DoesNotExist 異常 是 Publisher 這個 model 類的一個屬性,即 Publisher.DoesNotExist。在你的應(yīng)用中,你可以捕獲并處理這個異常

數(shù)據(jù)排序

>>> Publisher.objects.order_by("-state_province", "address")
 [<Publisher: Apress>, <Publisher: O'Reilly>]
 # 減號 - 前綴逆向排序,第二個字段會在第一個字段的值相同的情況下被使用到
class Publisher(models.Model):
    **class Meta:**
        **ordering = ['name']**
 # 在模型類(需要設(shè)置默認(rèn)排序的)中,設(shè)置默認(rèn)的排序方式,上述當(dāng)你使用 Django 的數(shù)據(jù)庫 API 去檢索時,
 # Publisher對象的相關(guān)返回值默認(rèn)地都會按 name 字段排序

連鎖查詢

>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
# 即為SQL查詢 WHERE 和 ORDER BY 的組合

限制返回?cái)?shù)據(jù)

>>> Publisher.objects.order_by('name')[0:2]        # 即為OFFSET 0 LIMIT 2;
>>> Publisher.objects.order_by('-name')[0]        # 不能用負(fù)索引,但可以這樣變通

更新

>>> p = Publisher.objects.get(name='Apress')
>>> p.name = 'Apress Publishing'
>>> p.save()                    # 這樣操作會更新所有的列(不僅僅是name列的值)

指定更新

>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')    # id=52的表的name字段
>>> Publisher.objects.all().update(country='USA')        # 所有Publisher的country字段值
2            # update()方法會返回一個整型數(shù)值,表示受影響的記錄條數(shù)。

刪除對象

>>> p = Publisher.objects.get(name="O'Reilly")    # 刪除指定記錄
>>> p.delete()
>>> Publisher.objects.filter(country='USA').delete()    # 同時刪除多條記錄
>>> Publisher.objects.all().delete()

多對多用兩個循環(huán)獲取 .all 獲取所有(列表)  .first 獲取首個

<img src="`i`.`p_w_picpath`.`all`.`0`.`p_w_picpath`.`url`" alt="`i`.`title`"/>
{% for im in i.p_w_picpath.all %}<img src="`im`.`p_w_picpath`.`url`" alt="`im`.`name`"/>{% endfor %}

本文名稱:python_Django之模板模型
網(wǎng)站鏈接:http://muchs.cn/article24/gdegce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、企業(yè)建站、網(wǎng)頁設(shè)計(jì)公司、網(wǎng)站營銷、微信公眾號、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)