[ckan-dev] Adding a new field into Organization

Qifeng.Bai at csiro.au Qifeng.Bai at csiro.au
Thu May 8 06:16:02 UTC 2014


Hi, Nigal

I have followed your given example at https://github.com/okfn/ckanext-iati/blob/master/ckanext/iati/plugins.py#L22 to rewrite my code, I got an exception if I set:
BTW, I am using CKAN2.2. What I am trying to do is adding a new field called “project_leader” on “organization” item.

def group_types(self):
        # This plugin doesn't handle any special package types, it just
        # registers itself as the default (above).
        return ['organization']

Module ckan.controllers.group:187 in read     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> c.group_dict = self._action('group_show')(context, data_dict)
Module ckan.logic:419 in wrapped     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> result = _action(context, data_dict, **kw)
Module ckan.logic.action.get:1046 in organization_show     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> return _group_or_org_show(context, data_dict, is_org=True)
Module ckan.logic.action.get:989 in _group_or_org_show     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> group_dict = model_dictize.group_dictize(group, context)
Module ckan.lib.dictization.model_dictize:379 in group_dictize     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> search_results = logic.get_action('package_search')(context, q)
Module ckan.logic:419 in wrapped     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> result = _action(context, data_dict, **kw)
Module ckan.logic.action.get:1430 in package_search     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/project30>  view<http://127.0.0.1:5000/organization/project30>
>>  <http://127.0.0.1:5000/organization/project30> raise ValidationError(errors)
ValidationError: {'name': [u'Missing value']}



However, if I set
def group_types(self):
        # This plugin doesn't handle any special package types, it just
        # registers itself as the default (above).
        return ['']

it returns a normal “organization’ page, but of course there is no value for “project leader”

Here is my code:

class NlmpProjectFormPlugin(plugins.SingletonPlugin,DefaultGroupForm):

    plugins.implements(plugins.IConfigurer, inherit=True)
    plugins.implements(plugins.IGroupForm, inherit=True)


    # These record how many times methods that this plugin's methods are
    # called, for testing purposes.
    num_times_new_template_called = 0
    num_times_read_template_called = 0
    num_times_edit_template_called = 0
    num_times_search_template_called = 0
    num_times_history_template_called = 0
    num_times_package_form_called = 0
    num_times_check_data_dict_called = 0
    num_times_setup_template_variables_called = 0



    def is_fallback(self):
        # Return True to register this plugin as the default handler for
        # package types not handled by any other IDatasetForm plugin.
        return True


    def group_types(self):
        # This plugin doesn't handle any special package types, it just
        # registers itself as the default (above).
        return ['']

    def form_to_db_schema_options(self, options):
        ''' This allows us to select different schemas for different
        purpose eg via the web interface or via the api or creation vs
        updating. It is optional and if not available form_to_db_schema
        should be used.
        If a context is provided, and it contains a schema, it will be
        returned.
       '''
        schema = options.get('context', {}).get('schema', None)
        if schema:
            return schema

        if options.get('api'):
            if options.get('type') == 'create':
                return self.form_to_db_schema_api_create()
            else:
                return self.form_to_db_schema_api_update()
        else:
            return self.form_to_db_schema()



    def form_to_db_schema_api_create(self):
        schema = super(NlmpProjectFormPlugin, self).form_to_db_schema_api_create()
        schema = self._modify_group_schema(schema)
        logging.info("create:"+schema)
        return schema

    def form_to_db_schema_api_update(self):
        schema = super(NlmpProjectFormPlugin, self).form_to_db_schema_api_update()
        schema = self._modify_group_schema(schema)
        logging.info("update:"+schema)
        return schema

    def form_to_db_schema(self):
        _convert_to_extras = tk.get_converter('convert_to_extras')
        _ignore_missing = tk.get_validator('ignore_missing')

        default_validators = [_ignore_missing, _convert_to_extras]
        schema = super(NlmpProjectFormPlugin, self).form_to_db_schema()
        schema.update({
            'project_leader': default_validators,
        })

        logging.info(schema)

        return schema


    def db_to_form_schema(self):
        _convert_from_extras = tk.get_converter('convert_from_extras')
        _ignore_missing = tk.get_validator('ignore_missing')
        default_validators = [_ignore_missing, _convert_from_extras]

        schema = super(NlmpProjectFormPlugin, self).form_to_db_schema()
        schema.update({
            'project_leader': default_validators,
        })
        logging.info(schema)
        return schema

    def _modify_group_schema(self, schema):

        # Import core converters and validators
        _convert_to_extras = tk.get_converter('convert_to_extras')
        _ignore_missing = tk.get_validator('ignore_missing')

        default_validators = [_ignore_missing, _convert_to_extras]
        schema.update({
            'project_leader': default_validators,
        })

        return schema


From: ckan-dev [mailto:ckan-dev-bounces at lists.okfn.org] On Behalf Of Nigel Babu
Sent: Wednesday, 7 May 2014 3:19 PM
To: CKAN Development Discussions
Subject: Re: [ckan-dev] Adding a new field into Organization

Why don't you take a look at https://github.com/okfn/ckanext-iati/blob/master/ckanext/iati/plugins.py#L22. That's a fairly reasonable example of working code.

Nigel Babu
Developer, Open Knowledge

On 7 May 2014 05:27, <Qifeng.Bai at csiro.au<mailto:Qifeng.Bai at csiro.au>> wrote:
After I added

def is_fallback(self):
    return True
def group_types(self):
    return ['organization']

It reported an exception and let me set attribute: group_form, I define an attribute:
    def group_form(self):
        return 'organization/new_organization_form.html'

It gave another error:
dule ckan.controllers.group:463 in new     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> return render(self._new_template(group_type))
Module ckan.lib.base:224 in render     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> loader_class=loader_class)
Module pylons.templating:249 in cached_template     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> return render_func()
Module ckan.lib.base:129 in render_template     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> template_path, template_type = render_.template_info(template_name)
Module ckan.lib.render:49 in template_info     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> template_path = find_template(template_name)
Module ckan.lib.render:17 in find_template     [http://127.0.0.1:5000/_debug/media/plus.jpg]     <http://127.0.0.1:5000/organization/new>  view<http://127.0.0.1:5000/organization/new>
>>  <http://127.0.0.1:5000/organization/new> if os.path.exists(os.path.join(path, template_name.encode('utf-8'))):
AttributeError: 'NoneType' object has no attribute 'encode'


I copy my code below, Can you tell me what wrong in my code, please?

import logging

import ckan.plugins as plugins
import ckan.plugins.toolkit as tk
class NlmpProjectFormPlugin(plugins.SingletonPlugin):

    plugins.implements(plugins.IConfigurer, inherit=True)
    plugins.implements(plugins.IGroupForm, inherit=True)

    # These record how many times methods that this plugin's methods are
    # called, for testing purposes.
    num_times_new_template_called = 0
    num_times_read_template_called = 0
    num_times_edit_template_called = 0
    num_times_search_template_called = 0
    num_times_history_template_called = 0
    num_times_package_form_called = 0
    num_times_check_data_dict_called = 0
    num_times_setup_template_variables_called = 0

    def update_config(self, config):
        # Add this plugin's templates dir to CKAN's extra_template_paths, so
        # that CKAN will use this plugin's custom templates.
        tk.add_template_directory(config, 'templates')



    def is_fallback(self):
        # Return True to register this plugin as the default handler for
        # package types not handled by any other IDatasetForm plugin.
        return True

    def group_form(self):
        return 'organization/new_organization_form.html'

    def group_types(self):
        # This plugin doesn't handle any special package types, it just
        # registers itself as the default (above).
        return ['organization']


    def form_to_db_schema(self):
        schema=group_form_schema()
        schema.update({
            'project_leader': [ignore_missing, unicode, convert_to_extras]
            })
        return schema

    def db_to_form_schema(self):
        return {}


    # These methods just record how many times they're called, for testing
    # purposes.
    # TODO: It might be better to test that custom templates returned by
    # these methods are actually used, not just that the methods get
    # called.

    def setup_template_variables(self, context, data_dict):
        NlmpProjectFormPlugin.num_times_setup_template_variables_called += 1
        return super(NlmpProjectFormPlugin, self).setup_template_variables(
                context, data_dict)

    def new_template(self):
        NlmpProjectFormPlugin.num_times_new_template_called += 1
        return super(NlmpProjectFormPlugin, self).new_template()

    def read_template(self):
        NlmpProjectFormPlugin.num_times_read_template_called += 1
        return super(NlmpProjectFormPlugin, self).read_template()

    def edit_template(self):
        NlmpProjectFormPlugin.num_times_edit_template_called += 1
        return super(NlmpProjectFormPlugin, self).edit_template()

    def search_template(self):
        NlmpProjectFormPlugin.num_times_search_template_called += 1
        return super(NlmpProjectFormPlugin, self).search_template()

    def history_template(self):
        NlmpProjectFormPlugin.num_times_history_template_called += 1
        return super(NlmpProjectFormPlugin, self).history_template()

    def package_form(self):
        NlmpProjectFormPlugin.num_times_package_form_called += 1
        return super(NlmpProjectFormPlugin, self).package_form()

    # check_data_dict() is deprecated, this method is only here to test that
    # legacy support for the deprecated method works.
    def check_data_dict(self, data_dict, schema=None):
        NlmpProjectFormPlugin.num_times_check_data_dict_called += 1

From: ckan-dev [mailto:ckan-dev-bounces at lists.okfn.org<mailto:ckan-dev-bounces at lists.okfn.org>] On Behalf Of Nigel Babu
Sent: Tuesday, 6 May 2014 8:50 PM
To: CKAN Development Discussions
Subject: Re: [ckan-dev] Adding a new field into Organization

I think you'll also need to add
def is_fallback(self):
    return True
def group_types(self):
    return ['organization']

Nigel Babu
Developer, Open Knowledge

On 6 May 2014 11:15, <Qifeng.Bai at csiro.au<mailto:Qifeng.Bai at csiro.au>> wrote:
Hi, there

I have tried the example of adding fields to IDatasetField. This example works well. Also I have read the ExampleGroupForm @ https://github.com/okfn/ckanext-example/blob/master/ckanext/example/forms.py

What I need to do is to add “Leader” field into the organisation. I managed to extend the “new_organization_form.html” to create a field called ”project_leader”. Unfortunately, the value of this field was not saved.

Code in new_organization_form.html

{% block custom_fields %}
{{ form.input('project_leader', label=_('Project Leader'), id='field-project_leader', placeholder=_('Leader'), value=data.project_leader, error=errors.project_leader, classes=['control-medium']) }}
  {% if action == "edit" %}{{ super() }}{% endif %}
{% endblock %}

Code in the “form_to_db_schema”

def form_to_db_schema(self):
        schema=group_form_schema()
        schema.update({
            'project_leader': [ignore_missing, unicode, convert_to_extras]
            })
        return schema

Would you please tell me what’s wrong with my code?

Cheers





[cid:image001.gif at 01CC55BF.85E7FEB0]

Qifeng Bai
Software Engineer
CSIRO Land and Water
Black Mountain, Canberra

Ph: +61-2-62465704
Web: www.clw.csiro.au<http://www.clw.csiro.au>




_______________________________________________
ckan-dev mailing list
ckan-dev at lists.okfn.org<mailto:ckan-dev at lists.okfn.org>
https://lists.okfn.org/mailman/listinfo/ckan-dev
Unsubscribe: https://lists.okfn.org/mailman/options/ckan-dev


_______________________________________________
ckan-dev mailing list
ckan-dev at lists.okfn.org<mailto:ckan-dev at lists.okfn.org>
https://lists.okfn.org/mailman/listinfo/ckan-dev
Unsubscribe: https://lists.okfn.org/mailman/options/ckan-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.okfn.org/pipermail/ckan-dev/attachments/20140508/7de9036d/attachment-0003.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.jpg
Type: image/jpeg
Size: 361 bytes
Desc: image001.jpg
URL: <http://lists.okfn.org/pipermail/ckan-dev/attachments/20140508/7de9036d/attachment-0003.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.gif
Type: image/gif
Size: 2094 bytes
Desc: image002.gif
URL: <http://lists.okfn.org/pipermail/ckan-dev/attachments/20140508/7de9036d/attachment-0003.gif>


More information about the ckan-dev mailing list