Clone wiki

web2py_crud / crud-options

CRUD Options

This page describes some more advanced usage of CRUD.


This is the method that creates a CRUD instance:

def plugin_crud(tablename,
                hidden_fields={'a': '1'},

As you can see, it has many options to make CRUD operations as customizable as possible. Let's go through each of these options one by one:



The label is how you want the tablename to be shown to the user. For example, the prompt "Are you sure you want to delete this x?", where x is the label. By default, the tablename is used for the label.


With web2py's FORM method, you can create forms with hidden fields that are included as part of the post back. You can pass a dictionary of your own key/value pairs here. By default, it contains one item: 'a': 1. This is for the purposes of generating a valid URL.

create_url / update_url

Sometimes you just need to create your own FORMs, whether for custom validation or even using SQLFORM.factory(). This parameter allows you to pass a string containing the name of a custom action in your controller that will handle the creation of the FORM (extension should always be .load). While allowing you to create your own FORMs is great for providing you with as much flexibility as possible, there are a few things that you have to do in order to use this properly.

Your action needs to check security by using a shortcut provided by the plugin (do not use any auth decorators when using the auth parameters of the plugin). When using the auth parameters (listed below), you must provide a security check in order for the parameters to work with custom FORMs.

The other requirement is that you must only return the instance of the created FORM. When form.accepts() is called and the form passes validation, it must return only the string, 'OK'. This is how the plugin knows when a form has been submitted successfully and closes the create dialog.

Here is an example of using create_url:

def index():
    This creates a List/Details view which uses the CRUD instance and will
    also use the custom FORM creation action.
    crud = plugin_crud('product', create_url='create.load')
    list = crud_list_details('product', crud=crud)
    return dict(list=list)

def create():
    This is the action that gets called when the user clicks the Create
    button. Must return a FORM or 'OK' if form was accepted.

    # check for security options and see if current user has 'create'
    # permissions for the 'product' table. Even if the auth options
    # aren't used, it is still a good idea to have this line just in
    # case you want to use the auth options in the future.
    crud_check_security('create', 'product')

    def form_validation(form):
        if == 'none':
   = 'The word none cannot be used for the product name'

    form = SQLFORM('product', onvalidation=form_validation)
    if form.accepts(request.vars, session):
        return 'OK'

    return dict(form=form)

create_extra_elements / update_extra_elements

When a FORM is shown to the user, you can optionally include a list of extra HTML to be shown at the bottom of the FORM. If you simply wanted to include a message at the end of you form, you could use this parameter instead of having to create your own custom action and view.


This would be the same as adding the @auth.requires_login decorator to the top of create/update/delete actions. Set to either True or False. By default, this is False.


This would be the same as adding the @auth.requires_membership decorator to the top of create/update/delete actions. This should be set to the name of a group/role that the user should be a member of in order to participate in CRUD operations. This is set to None by default, which disables membership checking.


This checks for 'create', 'update', or 'delete' permissions (depending on the operation) on the tablename. This works similarly to web2py's CRUD method for checking permissions. Set this to True to perform checking, otherwise False. By default this is set to False.

Special Note on auth Parameters

All auth settings are optionally and are disabled by default. You may use only one of these options at a time. Do not mix these, as this is not supported. The auth_requires_membership and auth_requires_permission parameters automatically check to see if the user is logged in.

Using auth_requires_membership is convenient in cases where an 'Administrators' group should have access to everything without needing to explicitly give that group permissions to everything using auth.add_permission().

Using CRUD Without the List Components

If you want to use AJAX CRUD, but want to provide your own method for selecting records for updating, you can manually call the create, update, and delete JavaScript methods in your views. The following are the signatures for the JavaScript functions (on_finished is an optional function to execute once the form has been validated):

  • function tablename_crud_create_object(on_finished) {}
  • function tablename_crud_update_object(id, on_finished) {}
  • function tablename_crud_delete_delete(id, on_finished) {}

The name 'tablename' is set to the string passed for plugin_crud(tablename). So in our example above, using 'product' as our tablename to perform CRUD operations on, the following JavaScript methods would be generated in the view:

  • function product_crud_create_object(on_finished) {}
  • function product_crud_update_object(id, on_finished) {}
  • function product_crud_delete_delete(id, on_finished) {}

This allows multiple instances of CRUD to be used in the same view. The following is an example view that lists product names, allows new products to be created, and existing products to be updated using CRUD:

{{extend 'layout.html'}}

<a href="#" id="create_button">Create Product</a>
    {{for row in rows:}}
        <li><a href="#" data-id="{{}}" class="update_button">{{}}</a></li>

<script type="text/javascript">
    jQuery(function() {
        jQuery('#create_button').click(function() {

        jQuery('.update_button').click(function() {
            var id = jQuery(this).data('id');

This is a very simple example of using CRUD without one of the built-in list components. In practice, you would want to update the list whenever a record is created, updated, or deleted, and that's what the optional on_finished parameter is for. As an example, imagine you had a JavaScript function that refreshed the list after a create, update, or delete:

function refresh_products() {
    //function to refresh the list of products after a change

The following is an example of how you would call this refresh method after create, update, or delete is completed successfully, using the on_finished parameter:

jQuery('#create_button').click(function() {
    product_crud_create_object(function() {

jQuery('.update_button').click(function() {
    var id = jQuery(this).data('id');
    product_crud_update_object(id, function() {