示例#1
0
    def _get_add_edit_form(self, action_type, R=None):
        exclude_list = self._get_exclude_list(action_type)
        
        cols = get_columns(self.model, 'primary_key')
        ModelForm = dojo_model_form(self.model, self.db_session, exclude=exclude_list,
                                    field_args=self._get_modelform_field_args())

        #check for field data and set proper attributes accordingly
        print('==> %r' % self.add_edit_field_args)
        for field_name, field_data in list(self.add_edit_field_args.items()):
            field = getattr(ModelForm, field_name)

            if 'choices' in field_data or 'choices_fields' in field_data:
                print(" => making field %s into select list" % field_name)
                field.field_class = DojoSelectField

        if 'edit' == action_type:
            f = ModelForm(self.request.POST, R, request_obj=self.request, use_csrf_protection=True)
        else:
            f = ModelForm(self.request.POST, request_obj=self.request, use_csrf_protection=True)

        #check for field data and set proper attributes accordingly
        for field_name, field_data in list(self.add_edit_field_args.items()):
            field = getattr(f, field_name)

            if 'choices' in field_data:
                if 'coerce' in field_data:
                    field.coerce = field_data['coerce']
                else:
                    field.coerce = int

                field.choices = field_data['choices']
                #field.validators = []

            if 'choices_fields' in field_data:
                recs = self.db_session.query(*field_data['choices_fields']).all()

                table_cols = get_columns(self.model)
                for table_col in table_cols:
                    if table_col.property.columns[0].name == field_name and \
                       table_col.property.columns[0].nullable:

                        field.validators = []
                        recs.insert(0, (None, ''))

                field.choices = recs
                #field.validators = []

        return f
示例#2
0
    def _get_exclude_list(self, action_type):
        if self.add_edit_exclude:
            return self.add_edit_exclude

        log.info("determining exclude list")
        # exclude any relationships
        exclude_list = list(self.model.__mapper__.relationships.keys())
        log.info(exclude_list)

        if "add" == action_type:
            # get the columns and add any primary key columns to the
            # exlude list if their autoincrement is True
            cols = get_columns(self.model, "primary_key")
            for c in cols:
                if int == c.property.columns[0].type.python_type and 0 == len(c.property.columns[0].foreign_keys):
                    exclude_list.append(c.key)

        return exclude_list
示例#3
0
    def _get_exclude_list(self, action_type):
        if self.add_edit_exclude:
            return self.add_edit_exclude

        log.info('determining exclude list')
        # exclude any relationships
        exclude_list = list(self.model.__mapper__.relationships.keys())
        log.info(exclude_list)

        if 'add' == action_type:
            # get the columns and add any primary key columns to the
            # exlude list if their autoincrement is True
            cols = get_columns(self.model, 'primary_key')
            for c in cols:
                if int == c.property.columns[0].type.python_type and 0 == len(c.property.columns[0].foreign_keys):
                    exclude_list.append(c.key)

        return exclude_list
示例#4
0
    def _get_add_edit_form(self, action_type, R=None):
        exclude_list = self._get_exclude_list(action_type)

        cols = get_columns(self.model, "primary_key")
        ModelForm = dojo_model_form(
            self.model,
            self.db_session,
            exclude=exclude_list,
            field_args=self._get_modelform_field_args(),
        )

        # check for field data and set proper attributes accordingly
        print("==> %r" % self.add_edit_field_args)
        for field_name, field_data in list(self.add_edit_field_args.items()):
            field = getattr(ModelForm, field_name)

            if "choices" in field_data or "choices_fields" in field_data:
                print(" => making field %s into select list" % field_name)
                field.field_class = DojoSelectField

        if "edit" == action_type:
            f = ModelForm(
                self.request.POST,
                R,
                request_obj=self.request,
                use_csrf_protection=True,
            )
        else:
            f = ModelForm(
                self.request.POST,
                request_obj=self.request,
                use_csrf_protection=True,
            )

        # check for field data and set proper attributes accordingly
        for field_name, field_data in list(self.add_edit_field_args.items()):
            field = getattr(f, field_name)

            if "choices" in field_data:
                if "coerce" in field_data:
                    field.coerce = field_data["coerce"]
                else:
                    field.coerce = int

                field.choices = field_data["choices"]
                # field.validators = []

            if "choices_fields" in field_data:
                recs = self.db_session.query(*field_data["choices_fields"]).all()

                table_cols = get_columns(self.model)
                for table_col in table_cols:
                    if table_col.property.columns[0].name == field_name and table_col.property.columns[0].nullable:

                        field.validators = []
                        recs.insert(0, (None, ""))

                field.choices = recs
                # field.validators = []

        return f
示例#5
0
def add_admin_handler(config, db_session, models=None, route_name_prefix='',
                      url_pattern_prefix='', handler_class=None):
    """
    A utility function to quickly add all admin related routes and set them to the admin handler class with one function call,
    for example::

        from pyck.ext import add_admin_handler, AdminController
        from pyck.lib import get_models
        import my_application_package_name_here

        # Place this with the config.add_route calls
        add_admin_handler(config, db, get_models(my_application_package_name_here), 'admin', '/admin',
                          AdminController)

    :param config:
        The application config object

    :param db:
        The database session object

    :param models:
        Note: For backward compatibility this parameter can either be a list (old) or a dictionary (new).
        List/Dictionary of models for to include in the admin panel.
        get_models function can be used to include all models.

    :param route_name_prefix:
        Optional string prefix to add to all route names generated inside the admin panel.

    :param url_pattern_prefix:
        Optional string prefix to add to all admin section related url patterns

    :param handler_class:
        The AdminController handler class.

    """

    handler_class.db_session = db_session
    handler_class.models = models
    all_models = models_dict_to_list(models)

    for model in all_models:
        handler_class.table_models[model.__tablename__] = model

    handler_class.route_prefix = route_name_prefix

    config.add_route(route_name_prefix + 'admin_index', url_pattern_prefix + '/')
    config.add_view(handler_class, attr='index',
                    route_name=route_name_prefix + 'admin_index',
                    renderer='pyck:templates/admin/index.mako')

    if all_models:
        for model in all_models:
            add_edit_field_args = {}
            list_field_args = {}
            FK_cols = get_columns(model, 'foreign_key')

            for FK in FK_cols:

                db_col = list(FK.foreign_keys)[0].column.name
                display_col = db_col

                # If target column is integer, set the column next to it as display column,
                # for non-int columns keep the display column same as the db column
                db_col_python_type = None
                try:
                    db_col_python_type = list(FK.foreign_keys)[0].column.table.columns[db_col].type.python_type
                except:
                    pass

                if int == db_col_python_type:
                    table_cols = list(list(FK.foreign_keys)[0].column.table.columns.keys())
                    d_idx = table_cols.index(db_col) + 1
                    if len(table_cols) > d_idx:
                        display_col = table_cols[d_idx]

                db_col = list(FK.foreign_keys)[0].column.table.columns[db_col]
                display_col = list(FK.foreign_keys)[0].column.table.columns[display_col]
                add_edit_field_args[FK.name] = dict(choices_fields=[db_col, display_col])

                # See if there is any relationship for current FK col, if yes, add reference to target
                # column in target table using that relationship
                for RS in model.__mapper__.relationships:
                    r_col = list(RS.local_columns)[0]
                    if r_col.name == FK.name:
                        list_field_args[FK.name] = dict(display_field="%s.%s" % (RS.key, display_col.name))
                        break

            CC = type(model.__name__ + 'CRUDController', (pyck.controllers.CRUDController,),
                      {'model': model, 'db_session': db_session,
                       'base_template': handler_class.base_template,
                       'add_edit_field_args': add_edit_field_args,
                       'list_field_args': list_field_args,
                       'fetch_record_count': handler_class.display_record_count,
                       'template_extra_params': {'models': models,
                                                 'route_prefix': route_name_prefix,
                                                 'display_record_count': handler_class.display_record_count}
                      }
                     )

            #extra_actions = [
            #    'crud_friendly_name',
            #    'crud_add_edit_exclude',
            #    'crud_add_edit_field_args'
            #    'crud_list_sort_by',
            #    'crud_list_recs_per_page',
            #    'crud_list_max_pages',
            #    'crud_list_field_args',
            #    'crud_list_only',
            #    'crud_list_exclude',
            #    'crud_list_actions',
            #    'crud_list_per_record_actions',
            #    'crud_detail_actions'
            #]
            #
            #for extra_action in extra_actions:
            #    if hasattr(handler_class, extra_action) and model.__name__ in getattr(handler_class, extra_action):
            #        setattr(CC, extra_action.strip("crud_"), getattr(handler_class, extra_action)[model.__name__])

            props = [i for i in dir(handler_class) if not callable(getattr(handler_class, i)) and i.startswith('crud_')]

            for extra_action in props:
                if model.__name__ in getattr(handler_class, extra_action):
                    setattr(CC, extra_action[5:], getattr(handler_class, extra_action)[model.__name__])

            add_crud_handler(config, route_name_prefix + model.__name__,
                             url_pattern_prefix + '/' + model.__tablename__, CC)
示例#6
0
def add_admin_handler(config,
                      db_session,
                      models=None,
                      route_name_prefix='',
                      url_pattern_prefix='',
                      handler_class=None):
    """
    A utility function to quickly add all admin related routes and set them to the admin handler class with one function call,
    for example::

        from pyck.ext import add_admin_handler, AdminController
        from pyck.lib import get_models
        import my_application_package_name_here

        # Place this with the config.add_route calls
        add_admin_handler(config, db, get_models(my_application_package_name_here), 'admin', '/admin',
                          AdminController)

    :param config:
        The application config object

    :param db:
        The database session object

    :param models:
        Note: For backward compatibility this parameter can either be a list (old) or a dictionary (new).
        List/Dictionary of models for to include in the admin panel.
        get_models function can be used to include all models.

    :param route_name_prefix:
        Optional string prefix to add to all route names generated inside the admin panel.

    :param url_pattern_prefix:
        Optional string prefix to add to all admin section related url patterns

    :param handler_class:
        The AdminController handler class.

    """

    handler_class.db_session = db_session
    handler_class.models = models
    all_models = models_dict_to_list(models)

    for model in all_models:
        handler_class.table_models[model.__tablename__] = model

    handler_class.route_prefix = route_name_prefix

    config.add_route(route_name_prefix + 'admin_index',
                     url_pattern_prefix + '/')
    config.add_view(handler_class,
                    attr='index',
                    route_name=route_name_prefix + 'admin_index',
                    renderer='pyck:templates/admin/index.mako')

    if all_models:
        for model in all_models:
            add_edit_field_args = {}
            list_field_args = {}
            FK_cols = get_columns(model, 'foreign_key')

            for FK in FK_cols:

                db_col = list(FK.foreign_keys)[0].column.name
                display_col = db_col

                # If target column is integer, set the column next to it as display column,
                # for non-int columns keep the display column same as the db column
                db_col_python_type = None
                try:
                    db_col_python_type = list(
                        FK.foreign_keys
                    )[0].column.table.columns[db_col].type.python_type
                except:
                    pass

                if int == db_col_python_type:
                    table_cols = list(
                        list(FK.foreign_keys)[0].column.table.columns.keys())
                    d_idx = table_cols.index(db_col) + 1
                    if len(table_cols) > d_idx:
                        display_col = table_cols[d_idx]

                db_col = list(FK.foreign_keys)[0].column.table.columns[db_col]
                display_col = list(
                    FK.foreign_keys)[0].column.table.columns[display_col]
                add_edit_field_args[FK.name] = dict(
                    choices_fields=[db_col, display_col])

                # See if there is any relationship for current FK col, if yes, add reference to target
                # column in target table using that relationship
                for RS in model.__mapper__.relationships:
                    r_col = list(RS.local_columns)[0]
                    if r_col.name == FK.name:
                        list_field_args[FK.name] = dict(
                            display_field="%s.%s" % (RS.key, display_col.name))
                        break

            CC = type(
                model.__name__ + 'CRUDController',
                (pyck.controllers.CRUDController, ), {
                    'model': model,
                    'db_session': db_session,
                    'base_template': handler_class.base_template,
                    'add_edit_field_args': add_edit_field_args,
                    'list_field_args': list_field_args,
                    'fetch_record_count': handler_class.display_record_count,
                    'template_extra_params': {
                        'models': models,
                        'route_prefix': route_name_prefix,
                        'display_record_count':
                        handler_class.display_record_count
                    }
                })

            #extra_actions = [
            #    'crud_friendly_name',
            #    'crud_add_edit_exclude',
            #    'crud_add_edit_field_args'
            #    'crud_list_sort_by',
            #    'crud_list_recs_per_page',
            #    'crud_list_max_pages',
            #    'crud_list_field_args',
            #    'crud_list_only',
            #    'crud_list_exclude',
            #    'crud_list_actions',
            #    'crud_list_per_record_actions',
            #    'crud_detail_actions'
            #]
            #
            #for extra_action in extra_actions:
            #    if hasattr(handler_class, extra_action) and model.__name__ in getattr(handler_class, extra_action):
            #        setattr(CC, extra_action.strip("crud_"), getattr(handler_class, extra_action)[model.__name__])

            props = [
                i for i in dir(handler_class)
                if not callable(getattr(handler_class, i))
                and i.startswith('crud_')
            ]

            for extra_action in props:
                if model.__name__ in getattr(handler_class, extra_action):
                    setattr(
                        CC, extra_action[5:],
                        getattr(handler_class, extra_action)[model.__name__])

            add_crud_handler(config, route_name_prefix + model.__name__,
                             url_pattern_prefix + '/' + model.__tablename__,
                             CC)