Revision: 12799
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at March 29, 2009 09:28 by wackysalut
Initial Code
### My App name = Vigilia
## in vigilia/forms/__init__.py
class FieldSet(forms.FieldSet):
def _render(self, **kwargs):
return render('/fieldset.mako',
extra_vars=kwargs)
def _render_readonly(self, **kwargs):
return render('/fieldset_readonly.mako',
extra_vars=kwargs)
def insert_after(self, after_what, field):
"""Insert a field to be rendered after a given field"""
idx = self._render_fields._list.index(after_what)
if idx is not None:
self.insert_at_index(idx + 1, field)
else:
raise ValueError('No such field in render_fields: %s' % after_what)
def insert_at_index(self, idx, field):
"""Insert a field to be rendered before a given field"""
if field.key in self._render_fields._list:
self._render_fields._list.remove(field.key)
self._render_fields._list.insert(idx, field.key)
self._render_fields[field.key] = field
class RadioSetRenderer(fields.RadioSet):
widget = staticmethod(h.radio)
def render(self, options, **kwargs):
self.radios = []
self.options = opts = options
for i, (choice_name, choice_value) in enumerate(opts):
choice_id = '%s_%i' % (self.name, i)
radio = self.widget(self.name, choice_name, id=choice_id,
checked=self._is_checked(choice_value), **kwargs)
label = h.make_tag('label', c=radio + ' %s' % choice_value)
self.radios.append(label)
return h.make_tag('div', c=h.make_tag("br").join(self.radios))
class CheckboxRenderer(RadioSetRenderer):
widget = staticmethod(h.checkbox)
class EmailSmsRenderer(fields.TextFieldRenderer):
pass
class PermissionField(fields.Field):
is_collection = False
is_composite_foreign_key = False
class PermissionsRenderer(fields.SelectFieldRenderer):
def render(self, **kwargs):
return h.select(self.name, [p.permission for p in self.field.model.permissions],
model.permissions_list,
size=len(model.permissions_list),
id=self.name, multiple=True)
def deserialize(self):
# This simple calculation makes sure we don't delete rows that
# haven't changed. We only add rows that were actually added,
# and remove the rows that were actually deleted from the last
# saved records.
u = self.field.model
p1 = set([perm.permission for perm in u.permissions])
p2 = set(self._params.getall(self.name))
p_rem = list(p1.difference(p2))
p_add = list(p2.difference(p1))
# Remove unwanted permissions..
u.permissions = [perm for perm in u.permissions
if perm.permission not in p_rem]
# Add new permissions
for x in p_add:
u.permissions.append(model.Permission(x))
return None
def password_validator(value, field):
if field.parent.passwd1.value != value:
raise validators.ValidationError('Les deux mots de passes ne concordent pas')
## in vigilia/model/___init___.py
# Permissions definitions
permissions_list = [
('admin', u'Administration globale'),
('moderation', u'Modération des commentaires'),
('posts_admin', u'Administration des posts'),
('posts_post', u'Poster un événement'),
('events_admin', u'Gestion des Activités'),
('logs_view', u'Visionnement des logs'),
]
# Users
users_t = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('username', String(25)),
Column('password', String(50)),
Column('firstname', Unicode(80)),
Column('lastname', Unicode(80)),
Column('gender', String(5), default='M'),
Column('email', Unicode(255)),
Column('email_sms', Unicode(150)),
Column('photo', Unicode(255)), # Lien relatif à une variable
# de configuration, vers l'image
Column('telephone', Unicode(100)),
Column('dob', Date), # Date of birth - Sans garder l'année
Column('pref_email_new_post', Boolean),
Column('pref_email_updt_post', Boolean),
Column('pref_email_sms_post', Boolean), # Only when asked for
Column('pref_email_new_event', Boolean),
Column('pref_email_updt_event', Boolean),
)
class User(object):
@property
def fullname(self):
"""Create the full-name representation of the user."""
if not self.firstname:
return unicode(self.username)
return self.firstname + \
(' %s' % self.lastname if self.lastname else '')
def __str__(self):
return self.fullname
def __repr__(self):
return "<User: %s>" % self.username
def __cmp__(self, other):
if self.firstname is None or other.firstname is None:
return 0
n1 = self.firstname + self.lastname
n2 = other.firstname + other.lastname
return cmp(n1, n2)
def has_perm(self, *args):
"""Checks if user has certain permissions"""
return has_perm(permissions=[p.permission for p in self.permissions],
*args)
mapper(User, users_t, {
'post_answers': relation(PostAnswer, lazy=True, backref='answer_user'),
'recipient_to': relation(Recipient, backref='user'),
'last_viewed': relation(LastViewed, backref='user'),
'permissions': relation(Permission),
'openids': relation(OpenID, backref='user'),
})
## in vigilia/controller/users.py
from vigilia.lib.base import *
log = logging.getLogger(__name__)
def gen_fieldset(mdl):
fs = forms.FieldSet(mdl)
fs.add(forms.Field('passwd1'))
fs.add(forms.Field('passwd2'))
fs.add(forms.PermissionField(name='permissions'))
fs.add(forms.Field('alert', value='').label(u'E-mail notification')\
.checkbox([('X', u'Envoyer un courriel avec ces informations '\
'au nouvel usager')])\
.with_renderer(forms.CheckboxRenderer))
inc = [fs.username.label(u"Nom d'usager"),
fs.passwd1.password().label(u'Mot de passe'),
fs.passwd2.password().label(u'Répétez le mot de passe').validate(forms.password_validator),
fs.gender.label(u'Genre').radio([('M', 'M'), ('F', 'F')]).with_renderer(forms.RadioSetRenderer),
fs.firstname.label(u'Prénom'),
fs.lastname.label(u'Nom de famille'),
fs.email.label(u'Courriel'),
fs.permissions.label(u'Permissions').with_renderer(forms.PermissionsRenderer),
fs.groups.label(u'Groupes'),
fs.email_sms.label(u'Passerelle SMS (courriel)').with_renderer(forms.EmailSmsRenderer),
fs.dob.label(u'Date de naissance').with_renderer(forms.DateFieldRendererFr),
]
fs.configure(include=inc)
return fs
class UsersController(BaseController):
@has_perm('admin')
def index(self):
c.list = model.User.query().order_by('firstname, lastname').all()
return render('/users/index.html')
@has_perm('admin')
def edit(self, id):
# New or modify
if id:
c.usr = model.User.query.get(id)
else:
c.usr = model.User
c.permissions_list = model.permissions_list
fs = gen_fieldset(c.usr)
fs = fs.bind(c.usr, data=request.POST or None)
if not id:
# Require password if it's first adding..
fs.insert_after('passwd2', fs.alert)
fs.configure(options=[fs.passwd1.required()])
if request.POST and fs.validate():
fs.sync()
if fs.passwd1.value:
fs.model.password = fs.passwd1.value
push_flash(INFO, u"Le mot de passe de l'usager a été modifié")
if fs.alert.value:
### TODO: send a notification e-mail here
push_flash(INFO, u"Un courriel de notification a été envoyé")
meta.Session.commit()
push_flash(SUCCESS, u"Usager sauvegardé avec succès")
redirect_to(controller='users', action='index')
c.fieldset = fs
return render('/users/edit.html')
## in vigilia/lib/base.py
rom vigilia import forms
Initial URL
Initial Description
This is based on FormEncode 1.2 + two patches you get here: http://code.google.com/p/formalchemy/issues/detail?id=83 and here: http://code.google.com/p/formalchemy/issues/detail?id=84 (at this point, they might be included in the official release).
Initial Title
FormAlchemy example with custom validator, renderers, forms - Pylons app
Initial Tags
Initial Language
Python