From: danigm Date: Sun, 7 Feb 2010 20:32:11 +0000 (+0100) Subject: Primeros pasos para tener un admin de modelos X-Git-Url: http://git.danigm.net/?p=webpysample.git;a=commitdiff_plain;h=ee7478250bae80c1e6e44554e026ec4b47061c25 Primeros pasos para tener un admin de modelos --- diff --git a/admin/__init__.py b/admin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/admin/admin.py b/admin/admin.py new file mode 100644 index 0000000..bc3092f --- /dev/null +++ b/admin/admin.py @@ -0,0 +1,49 @@ +import os +import web +from sqlalchemy.orm.attributes import QueryableAttribute + +import config + +PATH = os.path.realpath(__file__) + + +class AdminModel: + def __init__(self, model): + self.model = model + self.name = model.__name__ + self._get_fields() + + def _get_fields(self): + self.fields = {} + u = self.model + fields = [getattr(u, i) for i in dir(u) if isinstance(getattr(u, i), QueryableAttribute)] + for i in fields: + c = i.property.columns[0] + self.fields[c.name] = i + + +class Index: + def GET(self, *args): + ms = [AdminModel(i) for i in web.ctx.registered] + render = web.template.render('admin/templates', base='layout') + return render.index(ms) + +class AdminView: + def GET(self, id): + m = None + for i in web.ctx.registered: + m = AdminModel(i) + if m.name == id: + break + if not m: + raise web.seeother('/admin') + + orm = web.ctx.orm + render = web.template.render('admin/templates', base='layout') + + all = orm.query(m.model).all() + + return render.view(m, all) + + def POST(self): + pass diff --git a/admin/templates/index.html b/admin/templates/index.html new file mode 100644 index 0000000..47ccde6 --- /dev/null +++ b/admin/templates/index.html @@ -0,0 +1,6 @@ +$def with (models) + +$var title: Admin + +$for model in models: + $model.name
diff --git a/admin/templates/layout.html b/admin/templates/layout.html new file mode 100644 index 0000000..1cd220c --- /dev/null +++ b/admin/templates/layout.html @@ -0,0 +1,19 @@ +$def with (content) + + + + $content.title + + $if content.get('cssfiles', ''): + $for f in content.cssfiles.split(): + + + $if content.get('jsfiles', ''): + $for f in content.jsfiles.split(): + + + + + $:content + + diff --git a/admin/templates/view.html b/admin/templates/view.html new file mode 100644 index 0000000..fc98c0b --- /dev/null +++ b/admin/templates/view.html @@ -0,0 +1,9 @@ +$def with (model, all) + +$code: + title = 'Admin - ' + model.name + +$var title = title + +$for row in all: + $row
diff --git a/adminapp.py b/adminapp.py new file mode 100644 index 0000000..c37b66f --- /dev/null +++ b/adminapp.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import web +import db + +urls = ( + '', 'admin.admin.Index', + '/view/(?P.*)', 'admin.admin.AdminView', + ) + +registered = ( + db.User, + db.Test, + ) + +app = web.application(urls, globals()) + +def registration_hook(): + web.ctx.registered = registered +app.add_processor(web.loadhook(registration_hook)) + +if __name__ == '__main__': + app.run() diff --git a/app.py b/app.py index 7d5143a..51ab090 100644 --- a/app.py +++ b/app.py @@ -6,12 +6,15 @@ import db import config +import adminapp as admin + web.config.debug = config.DEBUG urls = ( - '/login', 'view.login.Login', - '/logout', 'view.login.Logout', + '/login', 'login.Login', + '/logout', 'login.Logout', '/reset', 'view.reset.Reset', + '/admin', admin.app, '/(.*)', 'view.index.Index') app = web.application(urls, globals()) diff --git a/login.py b/login.py new file mode 100644 index 0000000..fff6962 --- /dev/null +++ b/login.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +import web +from web import form +from db import User + +def get_user(authuser=''): + ''' + Devuelve el usuario autenticado + ''' + session = web.ctx.session + orm = web.ctx.orm + user = None + if not authuser: + authuser = session.get('username', '') + if authuser: + user = orm.query(User).filter(User.name == authuser).one() + + return user + +# decorators + +def authenticated(function): + ''' + Si es un usuario autenticado permite el acceso al recurso, sino + redirige a /login + ''' + session = web.ctx.session + def decorated(*args, **kwargs): + if session.get('username', ''): + return function(*args, **kwargs) + else: + raise web.seeother('/login') + + return decorated + + +class Login: + vname = form.regexp("\w*$", 'Alphanumeric only') + vpass = form.regexp(r".{3,20}", 'Must be between 3 and 20 chars') + + logform = form.Form( + form.Textbox("username", vname, description="User"), + form.Password("password", vpass, description="Password"), + ) + def GET(self, *args): + return web.ctx.render.login(self.logform()) + + def POST(self, *args): + orm = web.ctx.orm + session = web.ctx.session + + lform = self.logform() + if not lform.validates(): + return web.ctx.render.login(lform) + + values = web.input() + name = values['username'] + pwd = values['password'] + + query = orm.query(User).filter(User.name == name) + # si no existe se crea + if not query.count(): + u = User(name, pwd) + orm.add(u) + + user = query.one() + if user.auth(pwd): + session.username = name + raise web.seeother('/index') + else: + # hack + lform.username.note = 'wrong password' + return web.ctx.render.login(lform) + + +class Logout: + @authenticated + def GET(self): + web.ctx.session.username = '' + raise web.seeother('/index') + + diff --git a/view/login.py b/view/login.py deleted file mode 100644 index fff6962..0000000 --- a/view/login.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- - -import web -from web import form -from db import User - -def get_user(authuser=''): - ''' - Devuelve el usuario autenticado - ''' - session = web.ctx.session - orm = web.ctx.orm - user = None - if not authuser: - authuser = session.get('username', '') - if authuser: - user = orm.query(User).filter(User.name == authuser).one() - - return user - -# decorators - -def authenticated(function): - ''' - Si es un usuario autenticado permite el acceso al recurso, sino - redirige a /login - ''' - session = web.ctx.session - def decorated(*args, **kwargs): - if session.get('username', ''): - return function(*args, **kwargs) - else: - raise web.seeother('/login') - - return decorated - - -class Login: - vname = form.regexp("\w*$", 'Alphanumeric only') - vpass = form.regexp(r".{3,20}", 'Must be between 3 and 20 chars') - - logform = form.Form( - form.Textbox("username", vname, description="User"), - form.Password("password", vpass, description="Password"), - ) - def GET(self, *args): - return web.ctx.render.login(self.logform()) - - def POST(self, *args): - orm = web.ctx.orm - session = web.ctx.session - - lform = self.logform() - if not lform.validates(): - return web.ctx.render.login(lform) - - values = web.input() - name = values['username'] - pwd = values['password'] - - query = orm.query(User).filter(User.name == name) - # si no existe se crea - if not query.count(): - u = User(name, pwd) - orm.add(u) - - user = query.one() - if user.auth(pwd): - session.username = name - raise web.seeother('/index') - else: - # hack - lform.username.note = 'wrong password' - return web.ctx.render.login(lform) - - -class Logout: - @authenticated - def GET(self): - web.ctx.session.username = '' - raise web.seeother('/index') - -