If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

Sometimes I want to create a better administration panel for our clients. With this hack you can create an add/edit/delete panel for every table you like and extend it easily. in order to use it you just go inside the controllers and add:

@scaffold(None)
def authors():
    pass

this will create an admin page (authors) that has all the properties from the table "authors". if you have to "admin" a different table just put it's name:

@scaffold("other_table")
def authors():
    pass

Read the comments for more hacks. PS: I have also a new version that you can pass custom queries (I'll keep you updated). PS2: Also a version with DataTables (http://datatables.net/)

You can also chain decorators in order to prevent unauthorized access:

@auth.requires_login()
@scaffold("other_table")
def authors():
    pass

Now, the installation:

First, put this code inside a module (or in a separate file in models).

def scaffold(tbl_name=None, field_id=None): """ Decorator that exposes show/add/edit/delete for admin purposes

    You can specify a table name else it will use the
    name of the function as table name
    You can specify a field id that will be displayed for the record
    else it will use the first field value
    """

    def decorator_outside(func):

        def decorator_inside(*args):

            db_name = db # we could get the database name from globals
            table_name = func.__name__ if tbl_name == None else tbl_name
            if table_name not in db_name.tables:
                raise Exception("No table with name '%s' found" % table_name)

            form = None
            if len(request.args) > 1:
                action = request.args[0]
                record_id = request.args[1]

                if action == 'create':
                    form = crud.create(db_name[table_name])

                elif action == 'show':          
                    form = crud.read(db_name[table_name], record_id)

                elif action == 'edit':          
                    form = crud.update(db_name[table_name], record_id)

                elif request.args[0] == 'delete':           
                    form = crud.delete(db_name[table_name], record_id)

            result = db_name(db_name[table_name].id > 0).select()       
            func()

            return dict(rows=result, cntr_name=table_name, form=form, field_id=field_id)
        return decorator_inside

    return decorator_outside

The do the action in the controller @scaffold("other_table") def authors(): pass

Finally create a view file:

{{extend 'layout.html'}}
{{ include 'scaffold.html' }}

and paste this into your views folder:

{{= form if form != None else "" }}
<br />
<table>
  {{ i = 0 }}
  {{ for row in rows: }}
  {{ i += 1 }}
  <tr class="{{='even' if i%2 else 'odd'}}">
    <td class='main'><a href="{{= URL(r=request, f=cntr_name+'/show',
                     args=row.id) }}">{{= row.values()[field_id] }}</a></td>
    <td><a href="{{= URL(r=request, f=cntr_name+'/edit',
                     args=row.id) }}">Edit</a></td>
    <td><a href="{{= URL(r=request, f=cntr_name+'/delete',
                     args=row.id) }}">Delete</a></td>
  </tr>
  {{ pass }}
</table>

{{ if not len(rows): }}
No records found
{{ pass }}

<br />
<a href="{{= URL(r=request, f=cntr_name+'/create/new') }}">Add new</a>

Related slices

Comments (1)


Hosting graciously provided by:
Python Anywhere