| Author: | Copyright (C) 2007 Dipl.-Inform. Christoph Haas <email@christoph-haas.de> |
|---|---|
| IRC: | Meet me at #pylons on irc.freenode.net as Signum |
| License: | This document is published under the terms of the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. |
Note
O fonte desse documento está disponível em um repositório Mercurial em http://workaround.org/cgi-bin/hg-pylons-cheatsheet - por favor, envie patches para email@christoph-haas.de mesmo que você esteja lendo esse texto em wiki.pylonshq.com. Obrigado.
Contents
(%(here)s refere-se a raiz do projeto (onde está o development.ini))
from pylons import config
my_setting = config['foo.bar']
| data/sessions | Sessões são salvas em arquivos nesse diretório. |
| data/templates | Arquivos HTML em cache que são renderizados a partir de seus templates são armazenados aqui. |
| development.ini | A configuração de inicialização do Paste. |
| myapplication/config/ | Arquivos de configuração globais do seu projeto. Usados para definir rotas para o processamento de URLS, middleware (como a adição de autentição) ou o sistema de template de sua preferência |
| myapplication/controllers/ | A localização das classes que contém a lógica da sua aplicação. Esse código controla sua aplicação, renderiza templates e consulta o banco de dados. |
| myapplication/docs/ | Coloque qualquer documentação da aplicação aqui. De preferência no formato rest (restructured text). |
| myapplication/i18n/ | Arquivos que lidam com as mensagens localizadas do seu projeto. (i18n = internacionalização) |
| myapplication/lib/ | Contém arquivos que configuram certas variáveis globais e objetos que você pode usar em seus controladores. Por exemplo, tudo em lib/base.py está disponível em todos os seus controladores. |
| myapplication/model/ | Aqui vai o model do seu banco de dados. Eles definem o esquema do banco de dados e configuram o mapeamento objeto-relacional |
| myapplication/public/ | Arquivos estáticos como imagens, CSS ou javascripts devem ficar aqui |
| myapplication/templates/ | Seus templates |
| myapplication/tests/ | Cada controlador que você cria ganha uma contraparte para implementar testes automatizados aqui. |
| README.txt | Algumas instruções básicas que você pode dar ao administrador que irá instalar sua aplicação |
| ez_setup, myapplication.egg-info, setup.cfg, setup.py | Arquivos administrativos que são usados para criar um egg do seu projeto para que possa ser feito o deploy no servidor web. |
| test.ini | Semelhante ao development.ini. Esse arquivo é usando quando você quer rodar testes automatizados no seu projeto |
def index(self, id):
return 'Your ID is ' + id
response.headers['content-type'] = 'text/xml; charset=utf-8'
response.set_cookie('sitelang', 'uk')
response.status_code = 201
Os dados da configuração estão disponíveis através do objeto config
dicionário config['app_conf']
dicionário config['global_conf']
Caminho absoluto do arquivo ini: config['__file__']
Nome da aplicação: config['package'] or config['pylons.package']
Caminho para o projeto atual: config['here']
O objeto 'h' (webhelpers): config['pylons.h'] (configurado em config/environment.py)
O objeto 'g' (globals): config['pylons.g'] (configurado em config/environment.py)
localizados): config['pylons.paths'] (configurado em config/environment.py)
# -*- coding: utf-8 -*-
<?xml version="1.0" encoding="UTF-8"?>
<!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" lang="en" xml:lang="en">
<head>
<title>...........</title>
${ h.stylesheet_link_tag( '/style1.css', '/style2.css') }
${ h.javascript_include_tag( 'jquery.js', 'jquery.debug.js') }
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
</head>
<body>
<h1>My application</h1>
${ next.body() }
</body>
</html>
# -*- coding: utf-8 -*-
<%inherit file="master.mako"/>
<p>Hello World</p>
Links de documentação
pylons.database e SAContext estão obsoletos!
development.ini:
sqlalchemy.url = sqlite:///%(here)s/phonebook.db sqlalchemy.url = mysql://username:password@host:3306/database sqlalchemy.url = postgres://username:password@host:5432/database sqlalchemy.url = oracle://username:password@host:1521/sidname
Opções
O MySQL fecha conexões inativas automaticamente. Você precisará:
sqlalchemy.pool_recycle = 3600
Imprimir todas as consultas para o console (você pode usar também o módulo 'logging' como descrito na Documentação do SQLAlchemy):
sqlalchemy.echo = True
Definindo tabelas e mapeamento objeto relacional in model/__init__.py
import sqlalchemy as sql
import sqlalchemy.orm as orm
# Define table
my_table = sql.Table(
'tablename', metadata,
sql.Column('id', sql.Integer, primary_key=True), # gets a sequence/serial assigned
sql.Column('othertable_id', sql.Integer, sql.ForeignKey("othertable.id"))
sql.Column('name', sql.Unicode(80), nullable=False, unique=True)
)
# Define object class for ORM-mapping (every object matches one row)
class MyModel(object):
def __repr__(self):
return "MyModel (%s)" % self.name
orm.mapper(MyModel, my_table)
Teste o acesso aos modelos mapeados confortavelmente usando paster shell
Criando consultas e obtendo resultados
Obter uma linha com certo conteúdo em um campo (levanta uma exceção se mais linhas são retornadas): model.Session.query(model.MyModel).filter_by(name='John').one()
Obter um iterador de itens combinando com certo critério: model.Session.query(model.MyModel).filter(model.MyModel.name=='John')
Obter um iterador de itens com certo conteúdo: model.Session.query(model.MyModel).filter_by(name='John')
Obter um iterador de itens selecionados por uma condição SQL personalizada: model.Session.query(model.MyModel).filter_by("id<:value and name=:name").params(value=224, name='fred')
Obter a linha com a chave primária 42: model.Session.query(model.MyModel).get(42)
Obter todas as linhas: model.Session.query(model.MyModel).all()
Obter a primeira linha: model.Session.query(model.MyModel).first()
Obter a única linha(levanta uma exceção se mais linhas são retornadas): model.Session.query(model.MyModel).one()
Obter um número limitado de linhas (como uma lista)
Ordenar linhas
Contar linhas em um resultado: model.Session.query(model.MyModel).count()
Joins (cuidado com produtos cartesianos): model.Session.query(model.Model1, model.Model2).all()
Use filter and filter_by for generative queries:
query = model.Session.query(model.MyModel) query = query.filter_by(name='John', type=189) query = query.filter_by(city='Hamburg') results = query.all()
Operadores lógicos
Operadores de consulta:
- ==
- <
- >
- <=
- >=
- startswith('foo')
- endswith('.com')
- like('%jean')
- between(100,500)
- in('A', 'CNAME', 'MX')
- + (concatenation of strings)
- op('...') (custom operator)
- ==None (NULL comparison)
Funções de consulta:
- Sintaxe geral: func.FUNCTIONNAME(...)
- e.g. func.count() or func.now()
Criando novos objetos:
new_object = model.MyModel()
new_object.name = 'Jane'
new_object.city = 'Tokio'
model.Session.flush() # not needed if set autoflush=True
model.Session.commit() # needed because SQLAlchemy 0.4 uses transactions everywhere
old_object = model.Session.query(model.MyModel).get(42)
old_object.city = 'Paris'
model.Session.flush() # not needed if set autoflush=True
model.Session.commit() # needed because SQLAlchemy 0.4 uses transactions everywhere
old_object = model.sac.query(model.MyModel).get(42)
model.Session.delete(old_object)
model.Session.flush() # not needed if set autoflush=True
model.Session.commit() # needed because SQLAlchemy 0.4 uses transactions everywhere
query = model.sql.select([model.MyModel.some_column])
result = model.Session.execute(query).fetchall() # or .fetchmany() or .fetchone()
development.ini
A variavel session vem de pylons.session e é importada em seu lib/base.py. Ela se comporta como um dicionário.
Carregando um valor da sessão:
value = session['whatever']
Salvando um valor na sessão:
session['whatever'] = value session.save()
Removendo uma chave da sessão:
del session['whatever'] session.save()
Limpando a sessão:
session.clear()
session.save()
# My form schema
class MySchema(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
days = formencode.validators.IntRange(min=0, max=365, not_empty=True)
name = formencode.validators.MaxLength(50)
# MySchema schema without the 'days' field
class MySchema2(MySchema):
days = None # (removes days field from the superclass)
# MySchema schema with additional 'comment' field
class MySchema3(MySchema):
comment = String(min=20)
Instale o Babel:
Edite o seu setup.py e habilite a seção message_extractors para interpretar strings gettext nos templates.
Use a função "_" (um alias para a função gettext) sempre que você precisar de strings normais.
- Controladores: _('Hello World')
- Templates Mako : ${ _('Hello World') }
Primeira vez:
- Criar um pot template no diretório i18n: python setup.py extract_messages
- Criar um arquivo po para cada idioma (aqui o idioma é 'es'): python setup.py init_catalog -l es
- Editar o arquivo po em i18n/es/LC_MESSAGES/*.po e adicionar strings traduzidas nos campos msgstr
- Compile the po files into mo files: python setup.py compile_catalog
Update:
- Overwrite the english pot template:: python setup.py extract_messages
- Update the po files with new strings (does not overwrite the already translated strings): python setup.py update_catalog -l es
- Compile the po files into mo files: python setup.py compile_catalog
Dica: paster serve --reload não detecta mudanças na internacionalização. Você irá precisar reiniciar o servidor web.
Para configurar a linguagem do gettext de acordo com a língua do navegador adicione isso ao seu lib/base.py:
def __before__(self):
user_agent_language = request.languages[0][0:2]
set_lang(user_agent_language)
request.languages is an array of preferred languages that the users sets in the browser. I.e. ['de', 'en', 'en-us'].
- FormAlchemy: Cria formulários HTML automaticamente a partir de schemas do SQLAlchemy (classes mapeadas)
- Paginator: Ajuda a dividir um número grande de resultados em páginas e permite que o usuário navegue entre as páginas
- DBSprockets: Automaticamente cria formulários do Toscawidget e validadores do Formencode para schemas (classes mapeadas)
...