python信息系统web版_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('world')

模板中是Hello $name!,结果:hello world!

模板中是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,本循环的外层循环对象

例如:

$for c in ["a", "b", "c", "d"]:

$loop.index$c

模板中定义函数$def

$def tr(values):

$for v in values:

$v

$def table(rows):

$for row in rows:

$:row

$ 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

$body

可以用模板对象引用这些属性,模板名为page.html:

>>> out = render.page('hello', 'hello world')

>>> out.title

u'hello'

>>> out.content_type

u'text/html'

>>> str(out)

'\n\n

\nhello world\n
\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)

-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

Layout

$:content

$def with(gname, fname)

Hi, $(gname) $(fname)

运行render.index(“Lisa”, “Hayes”),页面上打印Hi, Lisa Hayes,查看代码会发现最终代码就是index.html和layout.html合并在一起的结果,index.html中的内容被嵌入到layout.html中的$:content处。

在layout.html模板中还可以引用index.html中定义的var变量,这为程序带来了更多的灵活性,比如我们希望在不同的页面在使用同一个layout模板的时候能有不同的title,可以在使用layout的模板中定义如下一个var变量:

$var title:This is index.html

然后在layout.html中的title处修改为:

$content.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()

等价于:

username
password
Login

控件属性

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 '

Prepare for Launch!

'

j = '

Liftoff in %s...'

yield '

  • '

count = int(count)

for i in range(count,0,-1):

out = j % i

time.sleep(1)

yield out

yield '

'

time.sleep(1)

yield '

Lift off

'

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 = '' % (countdown - i)

yield output

time.sleep(delay)

if __name__ == "__main__":

app.run()

要流传输大文件,需要添加传输译码(Transfer-Encoding)区块头,这样才能一边下载一边显示。否则,浏览器将缓冲所有数据直到下载完毕才显示。

Django

一、环境

安装:pip install Django==xxx

二、应用

(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

(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

Title

{{hello}}

# 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,通过“对象.属性”调用

Title

{{article.title}}

{{article.content}}

# index.html中的for循环

Title

新文章

{% for article in articles %}

{{ article.title }}

{% endfor %}

(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支持tuple和list。tuple中只有一个元素时元素后加","

六、简单博客

(1)URL传参

# 1、应用中的urls.py,正则表达式中组名设置

urlpatterns = [

url(r'^article/(?P[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[0-9]+)$', views.article_page, name="article_page")

]

# 3、HTML下添加href超链接部分

Article Page

{{ article.title }}

{{ article.content }}

修改文章

模板中超链接目标地址格式:

{% url 'app_name:url_name' [参数] %}

app_name:

根urls.py,写在include()中,namespace='app_name'

url_name:

应用urls.py,写在url()中,name='url_name'

(3)表单设置

# 表单页面

Title

{% csrf_token %}

文章标题:

文章内容:

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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值