Python_web專題

Web.py

一、Templetor模板對象

(1)模板系統使用方式

在工程同級目錄下創建templates文件夾,在該文件夾內創建hello.html文檔,內容如下:

$def with (name)
Hello $name!

使用模板系統引用hello.html文檔方法:

# 方法一
render = web.template.render('templates')
print render.hello('world')
# 方法二
hello = web.template.frender('templates/hello.html')
print hello('world')

此外還有一個便捷方式:

# 方法三
template = "$def with (name)\nHello $name"
hello = web.template.Template(template)
print hello('world')

(2)語法注意事項

  • 模板中Python語句要以$開頭;

  • 傳入模板的參數如果是html格式,如果想正常顯示效果,引用該參數要用$:
    如:render.hello('<em>world</em>')
    模板中是Hello $name!,結果:hello <em>world</em>!
    模板中是Hello $:name!,結果:hello world!

  • 需要顯示$時,在web.py 0.2 templates中用$$,之后版本也可用\$

  • 添加注釋用$#,注釋一直至本行末

  • 模板中的控制結構,例如:

$for i in range(10): 
    I like $i

$for i in range(10): I like $i

$while a:
    hello $a.pop()

$if times > max: 
    Stop! In the name of love. 
$else: 
    Keep on, you can do it.

其中循環結構中有個特定語法loop可以使用:

loop.index: the iteration of the loop (1-indexed) ,表示當前循環體所在循環次數,由1開始計算
loop.index0: the iteration of the loop (0-indexed),表示當前循環體所在循環次數,由0開始計算
loop.first: True if first iteration,判斷當前循環是否為首次循環
loop.last: True if last iteration,判斷當前循環是否為末次循環
loop.odd: True if an odd iteration,表示當前循環體是否為第奇次循環,首次為奇數次,返回True
loop.even: True if an even iteration,表示當前循環體是否為第偶次循環
loop.parity: "odd" or "even" depending on which is true,當前循環體為奇數次返回odd,偶數次為even
loop.parent: the loop above this in nested loops,本循環的外層循環對象

例如:

<table>
$for c in ["a", "b", "c", "d"]:
    <tr class="$loop.parity">
        <td>$loop.index</td>
        <td>$c</td>
    </tr>
</table>
  • 模板中定義函數$def
$def tr(values):
    <tr>
    $for v in values:
        <td>$v</td>
    </tr>

$def table(rows):
    <table>
    $for row in rows:
        $:row
    </table>

$ data = [['a', 'b', 'c'], [1, 2, 3], [2, 4, 6], [3, 6, 9] ]
$:table([tr(d) for d in data])
  • 模板中定義代碼塊$code:
$code:
    x = "you can write any python code here"
    y = x.title()  $# 每個單詞首字母大寫

    def limit(s, width=10):
        """limits a string to the given width"""
        if len(s) >= width:
            return s[:width] + "..."
        else:
            return s
$limit(x)  $# 結果:you can wr...
$limit(y)  $# 結果:You Can Wr...
$z         $#結果:68
  • 模板中定義額外的屬性,字符串類型:
$def with (title, body)

$var title: $title
$var content_type: text/html

<div id="body">
$body
</div>

可以用模板對象引用這些屬性,模板名為page.html

>>> out = render.page('hello', 'hello world')
>>> out.title
u'hello'
>>> out.content_type
u'text/html'
>>> str(out)
'\n\n<div>\nhello world\n</div>\n'
  • 設置模板的全局變量,適用于所有模板:
$# web.py 0.2 版本
render = web.template.render("templates/",globals={"user":"123"})
$# 之后版本還可以
render = web.template.render("templates/")
web.template.Template.globals = {"user":"123"}

在其他文檔中使用$user即可調用123

  • 模板復用
    當多個頁面有著相同的結構框架的時候,可以將這個框架整合在一個模板中,通過模板復用的方式公用這個框架。

render=web.template.render(“templates”,base=”layout”)
這里傳入base參數設置復用模板,layout是templates下的layout.html模板,其中代碼如下,參數content用于接收其他模板的結果對象。

$def with (content)
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head>
        <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
        <title>Layout</title>
    </head>
    <body>
        $:content
    </body>
</html>
$def with(gname, fname)
    Hi, $(gname) $(fname)

運行render.index(“Lisa”, “Hayes”),頁面上打印Hi, Lisa Hayes,查看代碼會發現最終代碼就是index.htmllayout.html合并在一起的結果,index.html中的內容被嵌入到layout.html中的$:content處。
layout.html模板中還可以引用index.html中定義的var變量,這為程序帶來了更多的靈活性,比如我們希望在不同的頁面在使用同一個layout模板的時候能有不同的title,可以在使用layout的模板中定義如下一個var變量:
$var title:This is index.html
然后在layout.html中的title處修改為:
<title>$content.title</title>
這樣,訪問index.html時顯示在瀏覽器上的title就是This is index.html,而不是原來的Layout了。

二、Form Library表單

  • 需要引入包:from web import form
# input類:
Textbox - free form single line input (input type="text")
Password - free form single line that hides input (input type="password")
Textarea - free form multi line input (textarea)
Dropdown - mutually exclusive input for lists (select and options)
Radio - mutually exclusive input for a few options (input type="radio")
Checkbox - binary input (input type="checkbox")
Button - submit the form (button)
  • 簡單使用:
login = form.Form(
    form.Textbox('username'),
    form.Password('password'),
    form.Button('Login'),
)
f = login()
print f.render()

等價于:

<table>
    <tr><th><label for="username">username</label></th><td><input type="text" id="username" name="username"/><div class="post" style="display: none;"></div></td></tr>
    <tr><th><label for="password">password</label></th><td><input type="password" id="password" name="password"/><div class="post" style="display: none;"></div></td></tr>
    <tr><th><label for="Login"></label></th><td><button id="Login" name="Login">Login</button><div class="post" style="display: none;"></div></td></tr>
</table>
  • 控件屬性
form.textbox("firstname",
    form.notnull, #put validators first followed by optional attributes
    class_="textEntry", #gives a class name to the text box -- note the underscore
    pre="pre", #directly before the text box
    post="post", #directly after the text box
    description="please enter your name", #describes field, defaults to form name ("firstname")
    value="bob", #default value
    id="nameid", #specify the id
)

以及其他html的相關屬性:

myform2 = form.Form(
    form.textbox('phonenumber',
        size="12",
        maxlength="12"        )
)

三、使用子應用

例如:在blog.py

import web
urls = (
  "", "reblog",
  "/(.*)", "blog"
)

class reblog:
    def GET(self): raise web.seeother('/')

class blog:
    def GET(self, path):
        return "blog " + path

app_blog = web.application(urls, locals())

當前的主應用code.py

import web
import blog
urls = (
  "/blog", blog.app_blog,
  "/(.*)", "index"
)

class index:
    def GET(self, path):
        return "hello " + path

app = web.application(urls, locals())

if __name__ == "__main__":
    app.run()

四、獲取客戶端信息web.ctx

web.ctx基于threadeddict類,又被叫做ThreadDict。這個類創建了一個類似字典(dictionary-like)的對象,對象中的值都是與線程id相對應的。這樣做很妙,因為很多用戶同時訪問系統時,這個字典對象能做到僅為某一特定的HTTP請求提供數據(因為沒有數據共享,所以對象是線程安全的)
例如:訪問某頁面的用戶是從哪個網頁跳轉而來的

class example:
    def GET(self):
        referer = web.ctx.env.get('HTTP_REFERER', 'http://google.com')
        raise web.seeother(referer)

上述代碼用web.ctx.env獲取HTTP_REFERER的值。如果HTTP_REFERER不存在,就會將google.com做為默認值。接下來,用戶就會被重定向回到之前的來源頁面。

web.ctx另一個特性,是它可以被loadhook賦值。例如:當一個請求被處理時,會話(Session)就會被設置并保存在web.ctx中。由于web.ctx是線程安全的,所以我們可以象使用普通的python對象一樣,來操作會話(Session)。

ctx中的數據成員:Request

  • environ 又被寫做. env – 包含標準WSGI環境變量的字典。
  • home – 應用的http根路徑(譯注:可以理解為應用的起始網址,協議+站點域名+應用所在路徑)例:http://example.org/admin
  • homedomain – 應用所在站點(可以理解為協議+域名) http://example.org
  • homepath – 當前應用所在的路徑,例如: /admin
  • host – 主機名(域名)+用戶請求的端口(如果沒有的話,就是默認的80端口),例如: example.org, example.org:8080
  • ip – 用戶的IP地址,例如: xxx.xxx.xxx.xxx
  • method – 所用的HTTP方法,例如: GET
  • path – 用戶請求路徑,它是基于當前應用的相對路徑。在子應用中,匹配外部應用的那部分網址將被去掉。例如:主應用在code.py中,而子應用在admin.py中。在code.py中, 我們將/admin關聯到admin.app。 在admin.py中, 將/stories關聯到stories類。在 stories中, web.ctx.path就是/stories, 而非/admin/stories。形如: /articles/845
  • protocol – 所用協議,例如: https
  • query – 跟在'?'字符后面的查詢字符串。如果不存在查詢參數,它就是一個空字符串。例如: ?fourlegs=good&twolegs=bad
  • fullpath 可以視為 path + query – 包含查詢參數的請求路徑,但不包括'homepath'。例如:/articles/845?fourlegs=good&twolegs=bad

Response

  • status – HTTP狀態碼(默認是'200 OK') 401 Unauthorized 未經授權
  • headers – 包含HTTP頭信息(headers)的二元組列表。
  • output – 包含響應實體的字符串。

五、應用處理器

加載鉤子(loadhook)和卸載鉤子(unloadhook)分別在請求開始之前和結束之后執行

def my_loadhook():
    print "my load hook"

def my_unloadhook():
    print "my unload hook"

app.add_processor(web.loadhook(my_loadhook))
app.add_processor(web.unloadhook(my_unloadhook))

在eclipse中無顯示效果,可在命令行中運行python xxx.py,裝有兩版Python輸入py -2 xxx.py

六、自定義NotFound消息

設置自定義的NotFound消息:

def notfound():
    return web.notfound("Sorry, the page you were looking for was not found.")
    # You can use template result like below, either is ok:
    #return web.notfound(render.notfound())
    #return web.notfound(str(render.notfound()))

app.notfound = notfound

返回自定義的NotFound消息:

class example:
    def GET(self):
        raise web.notfound()

自定義500錯誤信息:

def internalerror():
    return web.internalerror("Bad, bad server. No donut for you.")

app.internalerror = internalerror

六、流傳輸大文件

import web
import time

urls = (
    "/",    "count_holder",
    "/(.*)",  "count_down",
    )
app = web.application(urls, globals())

class count_down:
    def GET(self,count):
        # These headers make it work in browsers
        web.header('Content-type','text/html')
        web.header('Transfer-Encoding','chunked')        
        yield '<h2>Prepare for Launch!</h2>'
        j = '<li>Liftoff in %s...</li>'
        yield '<ul>'
        count = int(count)
        for i in range(count,0,-1):
            out = j % i
            time.sleep(1)
            yield out
        yield '</ul>'
        time.sleep(1)
        yield '<h1>Lift off</h1>'

class count_holder:
    def GET(self):
        web.header('Content-type','text/html')
        web.header('Transfer-Encoding','chunked')        
        boxes = 4
        delay = 3
        countdown = 10
        for i in range(boxes):
            output = '<iframe src="/%d" width="200" height="500"></iframe>' % (countdown - i)
            yield output
            time.sleep(delay)

if __name__ == "__main__":
    app.run()

要流傳輸大文件,需要添加傳輸譯碼(Transfer-Encoding)區塊頭,這樣才能一邊下載一邊顯示。否則,瀏覽器將緩沖所有數據直到下載完畢才顯示。

Django

一、環境

二、應用

(1)創建工程

django-admin startproject myblog(項目名)

  • manage.py:項目管理器。項目進行交互的命令行工具集入口
  • myblog:項目的一個容器,包含項目最基本的配置,不建議修改目錄名稱
  • wsgi.py:Python服務器網關接口,Python應用與Web服務器之間的接口,與Web服務器通訊的關鍵,使Web服務器識別Python應用
  • url.py:URL配置文件
  • settings.py:項目核心配置文件
import os
# 項目根目錄
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 項目安全碼,自動生成
SECRET_KEY = '4jj(2(rmtrek@fmq$qgo#r^_^^#1c8d)64**hfr(0@)%+sz-j_'
# 調試設置
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# 設置允許訪問的地址,當DEBUG = False時需要設置
ALLOWED_HOSTS = []
# 已安裝的應用。自定義的應用需包含在里面才可使用
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
# 中間件,Django自帶的工具集
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# URL根配置文件
ROOT_URLCONF = 'myblog.urls'
# 模板配置,模板就是一個個HTML
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',
            ],
        },
    },
]

WSGI_APPLICATION = 'myblog.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
# 數據庫配置,默認sqlite3,使用其他數據庫參考上方網站
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
# 密碼認證
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
# 美式英語
LANGUAGE_CODE = 'en-us'
# 時區
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
# 靜態文件地址
STATIC_URL = '/static/'

python manage.py runserver [端口號]:設置端口號啟動服務,無端口號設置默認時為8000

Debug狀態下的默認頁面

(2)創建應用

python manage.py startapp blog(應用名)django-admin startapp blog(應用)

注意: 應用需要添加到setting.py中的INSTALLED_APPS中,才可使用

  • migrations:數據移植(遷移)模塊,內容自動生成
  • admin.py:當前應用的后臺管理系統配置
  • apps.py:當前應用的配置
  • models.py:數據模塊
  • tests.py:自動化測試模塊
  • views.py:執行響應的代碼
# 1、settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog'
]
# 2、views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello,world!")

編輯 views.py:

  • 每個響應對應一個函數,函數必須返回一個響應
  • 函數必須存在一個參數,一般約定為requset
  • 每個響應對應一個URL
# 3、urls.py
from django.conf.urls import url
from django.contrib import admin
import blog.views as bv

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', bv.index)
]

三、Templates

參考: Django之模板語言

(1)應用URL設置

# 1、在根urls.py 中引入include
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include("blog.urls"))
]
# 2、在APP(blog)目錄下新建urls.py,格式和根urls.py相同
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index)
]

配置URL時注意正則表達式尾部符號$/,^$限制空字符,最后應該由/結尾

(2)Templates

  • Templates:HTML文件,使用Django模板語言(DTL),也支持第三方模板(如Jinja2)
  • DTL初使用:
    rander()函數支持傳入dic類型參數,該參數是后臺傳遞給模板的參數,鍵為參數名。在模板中使用{{參數名}}來使用
# 1、在應用目錄下創建templates目錄,并在該目錄內創建index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{hello}}</h1>
</body>
</html>
# 2、修改應用views.py,返回render()
from django.shortcuts import render
def index(request):
    # 主要傳入:URL請求request,模板名(,傳遞給模板的參數,...)
    return render(request, "index.html", {"hello": "HELLO,BLOG"})
  • 注意:模板目錄必須以templates命名,否則無法識別
  • 問題:Django查找Templates時,按照INSTALLED_APPS中的添加順序查找Template。不同APP下Template目錄中的同名HTML文件會發生沖突
  • 解決方法:在APP的Templates目錄下創建以APP名為名稱的目錄,將html文件放入該目錄下,render()中參數改為render(request, "blog/index.html", {"hello": "HELLO,BLOG"})

四、Models

一個Model對應數據庫的一張數據表,Django中Models以類的形式表示,它包含了一些基本字段以及數據的一些行為。

ORM:對象關系映射,實現了對象和數據庫之間的映射,隱藏了數據訪問的細節,不需要編寫SQL語句。

(1)創建Models

# APP目錄下models.py
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=32, default="Title")
    content = models.TextField(null=True)

(2)生成數據表

  • 1、遷移準備:python manage.py makemigrations [APP名]
    沒有指定APP名時,默認為該項目下所有應用都執行數據遷移
  • 2、遷移生成:python manage.py migrate
# migrations目錄下自動生成0001_initial.py
from __future__ import unicode_literals
from django.db import migrations, models

class Migration(migrations.Migration):
    initial = True
    dependencies = [
    ]
    operations = [
        migrations.CreateModel(
            name='Article',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(default='Title', max_length=32)),
                ('content', models.TextField(null=True)),
            ],
        ),
    ]

models中沒設置主鍵時自動創建id字段作為主鍵

  • 查看SQL生成語句:python manage.py sqlmigrate 應用名 文件id

默認在SQLite3數據庫下生成,在項目根目錄下db.sqlite3

(3)調用數據表

# views.py
from django.shortcuts import render
# 1、引入models
from . import models

def index(request):
    # 數據表中獲取主鍵為1的數據等價于`id=1`
    article = models.Article.objects.get(pk=1)
    # 傳入數據對象
    return render(request, "blog/index.html", {"article": article})
# index.html,通過“對象.屬性”調用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{article.title}}</h1>
<h2>{{article.content}}</h2>
</body>
</html>
# index.html中的for循環
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>
    <a href="">新文章</a>
</h1>
{% for article in articles %}
    <a href="" >{{ article.title }}</a>
    <br/>
{% endfor %}
</body>
</html>

(4)配置MySQL

  • 1、安裝mysqlclient(步驟2后runserver,如果提示安裝,按提示安裝相應庫)
# Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-g778k6pj/mysqlclient/
# apt-get install libmysql-dev
# apt-get install libmysqlclient-dev
# apt-get install python-dev
pip install mysqlclient
  • 2、Django中的設置
# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'app_data',
        'USER': 'root',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
  • 3、MySQL數據庫中已有的數據表映射到Django應用的models.py中(如果數據庫中已經設計了表結構的時候):
    python manage.py inspectdb > myapp/models.py
  • 4、Django應用所需的數據表遷移到MySQL數據庫內(包含Django自帶應用中的數據表):
    python manage.py migrate

五、Admin

Django自帶的一個功能強大的自動化數據管理界面,被授權的用戶可以直接在Admin中管理數據庫,并且可以定制功能。

  • 創建超級用戶:python manage.py createsuperuser
    密碼要求:8字符以上,不能是簡單密碼
  • Admin入口:localhost:8000/admin/
  • 設置Admin頁文字,在setting.py中修改LANGUAGE_CODE = 'zh_Hans'(簡體)/'zh_Hant(繁體)'
  • 配置應用:
# 1、在應用下admin.py中引入自身的models模塊
from django.contrib import admin
from .models import Article
# 2、Admin注冊
admin.site.register(Article)

引入同級模塊:from . import 模塊名
引入同級模塊下的類:from .模塊名 import 類名

  • 修改數據的默認顯示類型:
# models.py下修改類方法
class Article(models.Model):
    title = models.CharField(max_length=32, default="Title")
    content = models.TextField(null=True)

    def __str__(self):
        return self.title

Python2.x使用__unicode__(self),Python3.x使用__str__(self)

  • Admin配置類:
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
    # 實現列表多字段顯示
    list_display = ('title', 'content', 'pub_time')
    # 設置列表過濾
    list_filter = ('pub_time',)

# 綁定配置類
admin.site.register(Article, ArticleAdmin)

list_display支持tuplelist。tuple中只有一個元素時元素后加","

六、簡單博客

(1)URL傳參

# 1、應用中的urls.py,正則表達式中組名設置
urlpatterns = [
    url(r'^article/(?P<article_id>[0-9]+)$', views.article_page)
]
# 2、應用中的views.py,函數添加參數,與上方組名一致
def article_page(request, article_id):
    article = models.Article.objects.get(pk=article_id)
    return render(request, "blog/article_page.html", {"article": article})

URL中設置正則表達式的組名,該組名需要與對應函數中的參數名一致,才可傳遞參數

(2)模板添加超鏈接

# 1、根urls.py,給應用添加命名空間
urlpatterns = [
    url(r'^blog/', include("blog.urls", namespace='blog'))
]
# 2、應用url.py,給URL添加名稱
urlpatterns = [
    url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name="article_page")
]
# 3、HTML下添加href超鏈接部分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Article Page</title>
</head>
<body>
<h1>{{ article.title }}</h1>
<br/>
<h3>{{ article.content }}</h3>
<br/>
<br/>
<a href="{% url 'blog:edit_page' article.id %}">修改文章</a>
</body>
</html>

模板中超鏈接目標地址格式:
{% url 'app_name:url_name' [參數] %}

  • app_name
    urls.py,寫在include()中,namespace='app_name'
  • url_name
    應用urls.py,寫在url()中,name='url_name'

(3)表單設置

# 表單頁面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="{% url 'blog:edit_action'%}" method="post">
    {% csrf_token %}
    <label>文章標題:
        <input type="text" name="title"/>
    </label>
    <br/>
    <label>文章內容:
        <input type="text" name="content"/>
    </label>
    <br/>
    <input type="submit" value="提交">
</form>
</body>
  • form中請求方法action='目標URL',請求方式mathod='post'
  • form{% csrf_token %}能防止使用post提交表單時出現禁止訪問(403):CSRF驗證失敗
# 應用中的views.py
def edit_action(request):
    title = request.POST.get('title', 'TITLE')
    content = request.POST.get('content', 'CONTENT')
    models.Article.objects.create(title=title, content=content)
    
    # articles = models.Article.objects.all()
    # return render(request, "blog/index.html", {"articles": articles})

    return HttpResponseRedirect('/blog/article/')
  • request.POST['參數名']request.POST.get('參數名', '默認值')獲取post表單相應數據
  • return HttpResponseRedirect('/blog/article/')重定向URL

數據庫相應操作可通過操作Model對象完成:

  • models.Model對象類.objects.create(對象屬性)創建Model對象,相應數據庫添加數據
  • models.Model對象類.objects.get(對象屬性='屬性名')獲取Model對象,修改該對象屬性后,Model對象.save()保存修改,相應數據在數據庫中被修改

七、補充內容

(1)Templates過濾器

修改模板中的變量,從而顯示不同的內容
格式:{{value|filter|...}}
例如:{{value|default:'0'}}:設置value默認值為“0”

(2)Django Shell

一種Python的交互式命令行程序,并自動引入了項目環境,可與項目進行交互
作用:測試未知方法
啟動交互環境:python manage.py shell

from  blog.models import Article
# 查看所有Article對象
Article.objects.all()
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容