コード例 #1
0
    def get_o2m_defaults(self, o2m_values, model, o2m_model, name, view_type, view_id,
                         o2m_view_type, o2m_view_id, editable, limit, offset, o2m_context, o2m_domain):

        view_id = view_id or False
        o2m_view_id = ast.literal_eval(o2m_view_id) or False
        o2m_view_type = o2m_view_type or 'form'
        context = dict(ast.literal_eval(o2m_context), **rpc.get_session().context)
        o2m_values = simplejson.loads(o2m_values)

        for o2m in o2m_values:
            o2m['id'] = 0

        if o2m_view_id:
            view = cache.fields_view_get(o2m_model, o2m_view_id, o2m_view_type, context)
        else:
            view = cache.fields_view_get(model, view_id, view_type, rpc.get_session().context)
            view = view['fields'][name]['views'][o2m_view_type]

        list_view = listgrid.List(name, model, view, ids=None, domain=o2m_domain, context=context, default_data=copy.deepcopy(o2m_values), limit=20, editable= editable,o2m=1)
        view=ustr(list_view.render())
        formated_o2m_values = []
        for o2m in o2m_values:
            o2m.pop('id', None)
            formated_o2m_values.append((0, 0, o2m))

        return dict(view=view, formated_o2m_values=ustr(formated_o2m_values))
コード例 #2
0
 def do_drop(self, dbname, password, **kw):
     self.msg = {}
     try:
         rpc.get_session().execute_db('drop', password, dbname)
     except openobject.errors.AccessDenied, e:
         self.msg = {'message': _('Bad super admin password'),
                     'title' : e.title}
コード例 #3
0
    def custom_action(self, action):
        menu_ids = rpc.RPCProxy('ir.ui.menu').search(
                [('id', '=', int(action))], 0, 0, 0, rpc.get_session().context)

        return actions.execute_by_keyword(
                'tree_but_open', model='ir.ui.menu', id=menu_ids[0], ids=menu_ids,
                context=rpc.get_session().context, report_type='pdf')
コード例 #4
0
    def create(self, saved=False):

        tg_errors = None
        proxy = rpc.RPCProxy('res.users')
        action_id = proxy.action_get({})

        action = rpc.RPCProxy('ir.actions.act_window').read([action_id], False, rpc.get_session().context)[0]

        view_ids=[]
        if action.get('views', []):
            view_ids=[x[0] for x in action['views']]
        elif action.get('view_id', False):
            view_ids=[action['view_id'][0]]

        params = TinyDict()
        params.id = rpc.get_session().uid
        params.ids = [params.id]
        params.model = 'res.users'
        params.view_type = 'form'
        params.view_mode = ['form']
        params.view_ids = view_ids

        params.string = _('Preferences')

        params.editable = True
        form = self.create_form(params, tg_errors)

        return dict(form=form, params=params, editable=True, saved=saved)
コード例 #5
0
    def do_create(self, password, dbname, admin_password, confirm_password, demo_data=False, language=None, **kw):

        self.msg = {}
        if not re.match('^[a-zA-Z][a-zA-Z0-9_]+$', dbname):
            self.msg = {'message': ustr(_("You must avoid all accents, space or special characters.")),
                        'title': ustr(_('Bad database name'))}
            return self.create()

        ok = False
        try:
            res = rpc.get_session().execute_db('create', password, dbname, demo_data, language, admin_password)
            while True:
                try:
                    progress, users = rpc.get_session().execute_db('get_progress', password, res)
                    if progress == 1.0:
                        for x in users:
                            if x['login'] == 'admin':
                                rpc.get_session().login(dbname, 'admin', x['password'])
                                ok = True
                        break
                    else:
                        time.sleep(1)
                except:
                    raise DatabaseCreationCrash()
        except DatabaseCreationCrash:
            self.msg = {'message': (_("The server crashed during installation.\nWe suggest you to drop this database.")),
                        'title': (_('Error during database creation'))}
            return self.create()
        except openobject.errors.AccessDenied, e:
            self.msg = {'message': _('Bad super admin password'),
                        'title' : e.title}
            return self.create()
コード例 #6
0
    def button_action(self, **kw):
        params, data = TinyDict.split(kw)
        error = None
        reload = (params.context or {}).get('reload', False)
        result = {}

        name = params.button_name
        btype = params.button_type
        ctx = dict((params.context or {}), **rpc.get_session().context)

        id = params.id
        model = params.model

        id = (id or False) and int(id)
        ids = (id or []) and [id]
        list_grid = params.list_grid or '_terp_list'

        try:

            if btype == 'workflow':
                res = rpc.Workflow(model)[name](id)
                if isinstance(res, dict):
                    import actions
                    return actions.execute(res, ids=[id])
                else:
                    return dict(reload=True, list_grid=list_grid)

            elif btype == 'object':
                ctx = params.context or {}
                ctx.update(rpc.get_session().context.copy())
                res = rpc.RPCProxy(model)[name](ids, ctx)

                if isinstance(res, dict):
                    import actions
                    return actions.execute(res, ids=[id])
                else:
                    return dict(reload=True, list_grid=list_grid)

            elif btype == 'action':
                import actions

                action_id = int(name)
                action_type = actions.get_action_type(action_id)

                if action_type == 'ir.actions.wizard':
                    cherrypy.session['wizard_parent_form'] = '/form'
                    cherrypy.session['wizard_parent_params'] = params

                res = actions.execute_by_id(action_id, type=action_type, model=model, id=id, ids=ids, context=ctx or {})

                if res:
                    return res
                else:
                    return dict(reload=True, list_grid=list_grid)

            else:
                return dict(error = "Unallowed button type")
        except Exception, e:
            return dict(error = ustr(e))
コード例 #7
0
 def do_password(self, old_password, new_password, confirm_password, **kw):
     self.msg = {}
     try:
         rpc.get_session().execute_db('change_admin_password', old_password, new_password)
     except openobject.errors.AccessDenied, e:
         self.msg = {'message': _('Bad super admin password'),
                     'title' : e.title}
         return self.password()
コード例 #8
0
 def do_restore(self, filename, password, dbname, **kw):
     self.msg = {}
     try:
         data = base64.encodestring(filename.file.read())
         rpc.get_session().execute_db('restore', password, dbname, data)
     except openobject.errors.AccessDenied, e:
         self.msg = {'message': _('Bad super admin password'),
                     'title' : e.title}
         return self.restore()
コード例 #9
0
    def update_params(self, params):
        super(M2O, self).update_params(params)

        if params['value'] and not params['text']:
            try:
                value = expr_eval(params['value'], {'context':rpc.get_session().context})
            except:
                value = params['value']
            params['text'] = rpc.name_get(self.relation, value, rpc.get_session().context)
コード例 #10
0
    def add(self, id):
        id = int(id)

        if not self.by_res_id().get(id):
            name = rpc.RPCProxy('ir.ui.menu').name_get([id], rpc.get_session().context)[0][1]
            rpc.RPCProxy('ir.ui.view_sc').create({'user_id': rpc.get_session().uid, 'res_id': id, 'resource': 'ir.ui.menu', 'name': name})
            self.refresh_session()

        raise redirect('/openerp/tree/open', id=id, model='ir.ui.menu')
コード例 #11
0
    def menu(self, active=None, next=None):
        from openerp.widgets import tree_view
        
        try:
            id = int(active)
        except:
            id = False
            form.Form().reset_notebooks()
        ctx = rpc.get_session().context.copy()
        menus = rpc.RPCProxy("ir.ui.menu")

        domain = [('parent_id', '=', False)]
        user_menu_action_id = rpc.RPCProxy("res.users").read([rpc.session.uid], ['menu_id'], ctx)[0]['menu_id']
        if user_menu_action_id:
            act = rpc.RPCProxy('ir.actions.act_window').read([user_menu_action_id[0]], ['res_model', 'domain'], ctx)[0]
            if act['res_model'] == 'ir.ui.menu' and act['domain']:
                domain = literal_eval(act['domain'])

        ids = menus.search(domain, 0, 0, 0, ctx)
        parents = menus.read(ids, ['name', 'action', 'web_icon_data', 'web_icon_hover_data'], ctx)

        for parent in parents:
            if parent['id'] == id:
                parent['active'] = 'active'
                if parent.get('action') and not next:
                    next = url('/openerp/custom_action', action=id)
            # If only the hover image exists, use it as regular image as well
            if parent['web_icon_hover_data'] and not parent['web_icon_data']:
                parent['web_icon_data'] = parent['web_icon_hover_data']

        if next or active:
            if not id and ids:
                id = ids[0] 
            ids = menus.search([('parent_id', '=', id)], 0, 0, 0, ctx)
            tools = menus.read(ids, ['name', 'action'], ctx)
            view = cache.fields_view_get('ir.ui.menu', 1, 'tree', {})
            fields = cache.fields_get(view['model'], False, ctx)
            
            for tool in tools:
                tid = tool['id']
                tool['tree'] = tree = tree_view.ViewTree(view, 'ir.ui.menu', tid,
                                        domain=[('parent_id', '=', tid)],
                                        context=ctx, action="/openerp/tree/action", fields=fields)
                tree._name = "tree_%s" %(tid)
                tree.tree.onselection = None
                tree.tree.onheaderclick = None
                tree.tree.showheaders = 0
        else:
            # display home action
            tools = None

        return dict(parents=parents, tools=tools, load_content=(next and next or ''),
                    welcome_messages=rpc.RPCProxy('publisher_warranty.contract').get_last_user_messages(_MAXIMUM_NUMBER_WELCOME_MESSAGES),
                    show_close_btn=rpc.get_session().uid == 1,
                    widgets=openobject.pooler.get_pool()\
                                      .get_controller('/openerp/widgets')\
                                      .user_home_widgets(ctx))
コード例 #12
0
 def ok(self, **kw):
     params, data = TinyDict.split(kw)
     proxy = rpc.RPCProxy('res.users')
     # validators generally do that...
     for key in data.keys():
         if not data[key]: data[key] = False
         elif int_pattern.match(data[key]):
             data[key] = int(data[key])
     proxy.write([rpc.get_session().uid], data)
     rpc.get_session().context_reload()
     raise redirect('/openerp/pref/create', saved=True)
コード例 #13
0
 def can_shortcut_create(self):
     """ We only handle creating shortcuts to menu actions (for now
     anyway), and those go through the execute routine, so only match
     execute()d actions concerning ir.ui.menu. And trees, just because
     """
     action_data = cherrypy.request.params.get('data', {})
     return (rpc.get_session().is_logged() and
             rpc.get_session().active_id and
             ((cherrypy.request.path_info == '/openerp/execute'
               and action_data.get('model') == 'ir.ui.menu')
             # FIXME: hack hack hack
              or cherrypy.request.params.get('_terp_source_view_type') == 'tree'))
コード例 #14
0
def search(model, offset=0, limit=50, domain=[], context={}, data={}):
    """A helper function to search for data by given criteria.

    @param model: the resource on which to make search
    @param offset: offset from when to start search
    @param limit: limit of the search result
    @param domain: the domain (search criteria)
    @param context: the context
    @param data: the form data

    @returns dict with list of ids count of records etc.
    """

    domain = domain or []
    context = context or {}
    data = data or {}

    proxy = rpc.RPCProxy(model)
    fields = proxy.fields_get([], rpc.get_session().context)

    search_domain = domain[:]
    search_data = {}

    for k, v in data.items():
        t = fields.get(k, {}).get('type', 'char')
        t = make_domain(k, v, t)

        if t:
            search_domain += t
            search_data[k] = v

    l = limit
    o = offset

    if l < 1: l = 50
    if o < 0: o = 0

    ctx = rpc.get_session().context.copy()
    ctx.update(context)

    ids = proxy.search(search_domain, o, l, 0, ctx)
    if len(ids) < l:
        count = len(ids)
    else:
        count = proxy.search_count(search_domain, ctx)

    if isinstance(ids, list):
        count = len(ids)

    return dict(model=model, ids=ids, count=count, offset=o, limit=l,
                search_domain=search_domain, search_data=search_data)
コード例 #15
0
    def button_action_object(self, name, params):
        model, id, ids, ctx = self._get_button_infos(params)

        res = rpc.RPCProxy(model)[name](ids, ctx)
        # after installation of modules (esp. initial) we may
        # need values from the global context for some contexts & domains (e.g.
        # leads) => installer wizards are generally postfixed by '.installer'
        # so use this characteristic to setup context reloads
        if model.endswith('.installer'):
            rpc.get_session().context_reload()
        if isinstance(res, dict):
            import actions
            return actions.execute(res, ids=[id], context=ctx)
        params.button = None
コード例 #16
0
    def __init__(self, **attrs):
        super(Selection, self).__init__(**attrs)

        self.options = attrs.get('selection', [])
        self.type2 = attrs.get('type2')
        self.operator = attrs.get('operator', '=')
        self.search_context = attrs.get('context', {})
        #Below mentioned process should be followed for m2o as selection and for boolean field on search panel
        if (attrs.get('relation') and attrs.get('widget') == 'selection') or (not self.options and attrs.get('type','') != 'boolean'):
            proxy = rpc.RPCProxy(attrs['relation'])
            try:
                domain = attrs.get('domain', [])
                if isinstance(domain, (str, unicode)):
                    try:
                        domain = eval(domain)
                    except:
                        domain = []
                ids = proxy.search(domain)
                ctx = rpc.get_session().context.copy()
#                ctx.update(attrs.get('context', {})) # In search view this will create problem for m2o field having widget='selection' and context as attr.
                self.options = proxy.name_get(ids, ctx)
            except:
                self.options = []

        if self.options and self.options[0][0] == '' and isinstance(self.options[0][0], unicode):
            self.validator = validators.Selection()
        # determine the actual type
        elif self.options and isinstance(self.options[0][0], basestring):
            self.kind = 'char'
            self.validator = validators.String()
        else:
            self.validator = validators.Selection()
コード例 #17
0
    def export_data(self, fname, fields, import_compat=False, export_format='csv', **kw):

        params, data_index = TinyDict.split(kw)
        proxy = rpc.RPCProxy(params.model)

        flds = []
        for item in fields:
            fld = item.replace('/.id','.id')
            flds.append(fld)

        if isinstance(fields, basestring):
            fields = fields.replace('/.id','.id')
            flds = [fields]


        ctx = dict((params.context or {}), **rpc.get_session().context)
        ctx['import_comp'] = bool(int(import_compat))

        domain = params.seach_domain or []

        ids = params.ids or proxy.search(domain, 0, 0, 0, ctx)
        result = datas_read(ids, params.model, flds, context=ctx)

        if result.get('warning'):
            common.warning(unicode(result.get('warning', False)), _('Export Error'))
            return False
        result = result.get('datas',[])

        if import_compat:
            params.fields2 = flds

        if export_format == 'xls':
            return export_xls(params.fields2, result)
        else:
            return export_csv(params.fields2, result)
コード例 #18
0
    def exp(self, import_compat="1", **kw):

        params, data = TinyDict.split(kw)
        ctx = dict((params.context or {}), **rpc.get_session().context)

        views = {}
        if params.view_mode and params.view_ids:
            for i, view in enumerate(params.view_mode):
                views[view] = params.view_ids[i]

        exports = rpc.RPCProxy('ir.exports')

        headers = [{'string' : 'Name', 'name' : 'name', 'type' : 'char'}]
        tree = treegrid.TreeGrid('export_fields',
                                 model=params.model,
                                 headers=headers,
                                 url=tools.url('/openerp/impex/get_fields'),
                                 field_parent='relation',
                                 context=ctx,
                                 views=views,
                                 import_compat=int(import_compat))

        tree.show_headers = False

        existing_exports = exports.read(
            exports.search([('resource', '=', params.model)], context=ctx),
            [], ctx)

        return dict(existing_exports=existing_exports, model=params.model, ids=params.ids, ctx=ctx,
                    search_domain=params.search_domain, source=params.source,
                    tree=tree, import_compat=import_compat)
コード例 #19
0
    def refresh_session(self):
        ''' refresh_session() -> [{id, name, res_id}]

        Fetches the list of ir.ui.menu shortcuts from the server, stores them
        in session and returns the list.

        Returns only the id of the resource, not the retrieved (id, name_get())
        '''
        shortcuts = rpc.RPCProxy('ir.ui.view_sc')\
            .get_sc(rpc.get_session().uid, 'ir.ui.menu', rpc.get_session().context) or []
        for shortcut in shortcuts:
            # if res_id is (id, name), only keep id
            if isinstance(shortcut['res_id'], (list, tuple)):
                shortcut['res_id'] = shortcut['res_id'][0]
        cherrypy.session['terp_shortcuts'] = shortcuts
        return shortcuts
コード例 #20
0
    def __init__(self, model, view=False, view_id=False, ids=[], domain=[], context={},view_mode=[], group_by=[], width=360, height=300):

        name = 'graph_%s' % (random.randint(0,10000))
        super(Graph, self).__init__(name=name, model=model, width=width, height=height)

        ctx = rpc.get_session().context.copy()
        ctx.update(context or {})
        view = view or cache.fields_view_get(model, view_id, 'graph', ctx)

        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.string = attrs.get('string')
        self.group_by = group_by
        chart_type = attrs.get('type', 'pie')

        self.ids = ids

        if chart_type == "bar":
            self.data = BarChart(model, view, view_id, ids, domain, view_mode, context, group_by)
        else:
            self.data = PieChart(model, view, view_id, ids, domain, view_mode, context, group_by)

        self.data = simplejson.dumps(self.data.get_data())
コード例 #21
0
 def remove(self, id=False, **kw):
     proxy = rpc.RPCProxy('ir.attachment')
     try:
         proxy.unlink([int(id)], rpc.get_session().context)
         return {}
     except Exception, e:
         return {'error': ustr(e)}
コード例 #22
0
    def previous_o2m(self, **kw):
        params, data = TinyDict.split(kw)
        
        if params.get('_terp_save_current_id'):
            ctx = dict((params.context or {}), **rpc.get_session().context)
            if params.id:
                rpc.RPCProxy(params.model).write([params.id], data, ctx)
            else:
                id = rpc.RPCProxy(params.model).create(data, ctx)
                params.ids.append(id)
                params.count += 1
        
        current = params.chain_get(params.source or '') or params
        idx = -1
        
        if current.id:
            # save current record
            if params.editable:
                self.save(terp_save_only=True, **kw)

            idx = current.ids.index(current.id)
            idx = idx-1

            if idx == len(current.ids):
                idx = len(current.ids) -1

        if current.ids:
            current.id = current.ids[idx]

        return self.create(params)
コード例 #23
0
    def auto_create(self, conn_obj, src, des, act_from, act_to, **kw):
        conn_flds = eval(kw.get('conn_flds', '[]'))
        conn_flds_string = eval(kw.get('conn_flds_string', '[]'))
        proxy_tr = rpc.RPCProxy(conn_obj)

        if not(kw.get('id', False)):
            id = proxy_tr.create({src: act_from, des: act_to})
        else:
            id = int(kw['id'])

        if src not in conn_flds: conn_flds.append(src)
        if des not in conn_flds: conn_flds.append(des)

        result = proxy_tr.read(id, conn_flds, rpc.get_session().context)

        data = {
            'id': result['id'],
            's_id': result[src][0],
            'd_id': result[des][0],
            'source': result[src][1],
            'destination': result[des][1],
            'options': {}
        }

        for i, fld in enumerate(conn_flds):
            data['options'][conn_flds_string[i]] = result[fld]

        if id > 0:
            return {'flag': True, 'data': data}
        else:
            return {'flag': False}
コード例 #24
0
def _get_model(node, parent_model):

    parents = []
    pnode = node.parentNode

    while pnode:

        if pnode.localName == 'field':
            ch = utils.xml_locate('./form[1]', pnode) \
               + utils.xml_locate('./tree[1]', pnode) \
               + utils.xml_locate('./graph[1]', pnode) \
               + utils.xml_locate('./calendar[1]', pnode)

            if ch:
                parents.append(pnode.getAttribute('name'))

        pnode = pnode.parentNode

    parents.reverse()

    for parent in parents:
        field = rpc.RPCProxy(parent_model).fields_get([parent], rpc.get_session().context)

        if field:
            if field[parent].get('relation'):
                parent_model = field[parent]['relation']

    return parent_model
コード例 #25
0
    def get_groups(self, events):

        if not self.level:
            return []

        obj = self.level['object']
        field = self.level['link']

        keys = []
        groups = {}
        for evt in events:
            group_id = evt.record[field]
            group_title = 'None'

            if not group_id: # create dummy group
                group_id = 0

            if isinstance(group_id, (list, tuple)):
                group_id, group_title = evt.record[field]
            elif group_id:
                group_id, group_title = rpc.RPCProxy(obj).name_get([group_id], rpc.get_session().context)[0]

            group = groups.setdefault(group_id, {'id': str(group_id), 'title': group_title, 'model': obj, 'items': []})

            group['items'].append(str(evt.record_id))

            if group_id not in keys:
                keys.append(group_id)

        return [groups[i] for i in keys]
コード例 #26
0
    def _get_gantt_records(self, model, ids=None, group=None):

        if group:
            return [{
                'id': group['id'],
                'items': {'name': group['title']},
                'action': None,
                'target': None,
                'icon': None,
                'children': self._get_gantt_records(model, group['items'])
            }]

        proxy = rpc.RPCProxy(model)
        ctx = dict(rpc.get_session().context)

        records = []
        for id in ids:
            records.append({
                'id': id,
                'items': {'name': proxy.name_get([id], ctx)[0][-1]},
                'action': 'javascript: void(0)',
                'target': None,
                'icon': None,
                'children': None
            })

        return records
コード例 #27
0
    def create(self, params, tg_errors=None):

        params.path = self.path
        params.function = 'create_state'

        if params.id and cherrypy.request.path_info == self.path + '/view':
            params.load_counter = 2
        elif not params.context:
            params.context = {'o2m_model': params.o2m_model, 'o2m_id': params.o2m_id}

        proxy_field = rpc.RPCProxy('ir.model.fields')
        field_ids = proxy_field.search([('model', '=', params.o2m_model or params.context.get('o2m_model')), ('relation', '=', params.model)], 0, 0, 0, rpc.get_session().context)
        m2o_field = proxy_field.read(field_ids, ['relation_field'], rpc.get_session().context)[0]['relation_field']

        params.hidden_fields = [
            tw.form.Hidden(name=m2o_field, default=params.o2m_id or params.context.get('o2m_id', False)),
            tw.form.Hidden(name='_terp_o2m_model', default=params.o2m_model)]
        form = self.create_form(params, tg_errors)

        field = form.screen.widget.get_widgets_by_name(m2o_field)
        if field:
            field[0].set_value(params.o2m_id or params.context.get('o2m_id', False))
            field[0].readonly = True

        vals = getattr(cherrypy.request, 'terp_validators', {})
        vals[m2o_field] = validators.Int()

        hide = []

        for w in hide:
            w.visible = False

        return dict(form=form, params=params)
コード例 #28
0
    def moveDown(self, **kw):
        params, data = TinyDict.split(kw)

        id = params.id
        ids = params.ids or []

        if id not in ids or ids.index(id) == len(ids) - 1:
            return dict()

        proxy = rpc.RPCProxy(params.model)
        ctx = rpc.get_session().context.copy()

        next_id = ids[ids.index(id)+1]

        try:
            res = proxy.read([id, next_id], ['sequence'], ctx)
            records = dict([(r['id'], r['sequence']) for r in res])

            cur_seq = records[id]
            next_seq = records[next_id]

            if cur_seq == next_seq:
                proxy.write([next_id], {'sequence': cur_seq + 1}, ctx)
                proxy.write([id], {'sequence': next_seq}, ctx)
            else:
                proxy.write([id], {'sequence': next_seq}, ctx)
                proxy.write([next_id], {'sequence': cur_seq}, ctx)

            return dict()
        except Exception, e:
            return dict(error=str(e))
コード例 #29
0
    def add(self, view_id, xpath_expr):
        view_id = int(view_id)

        res = rpc.RPCProxy('ir.ui.view').read([view_id], ['model', 'arch'])[0]

        doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8'))
        model = res['model']

        field_node = utils.xml_locate(xpath_expr, doc)[0]
        model = _get_model(field_node, parent_model=model)

        # get the fields
        fields = rpc.RPCProxy(model).fields_get(False, rpc.get_session().context).keys()

        nodes = _CHILDREN.keys()
        nodes.remove('view')

        nodes.sort()
        fields.sort()

        positions = [('inside', 'Inside'), ('after', 'After'), ('before', 'Before')]
        if field_node.localName in [k for k,v in _CHILDREN.items() if not v] + ['field']:
            positions = [('after', 'After'), ('before', 'Before'), ('inside', 'Inside')]

        return dict(view_id=view_id, xpath_expr=xpath_expr, nodes=nodes, fields=fields, model=model, positions=positions)
コード例 #30
0
    def get_m2m(self, name, model, view_id, view_type, ids):
        view_id = ast.literal_eval(view_id) or False
        ids = ast.literal_eval(ids) or []
        view = cache.fields_view_get(model, view_id, view_type, rpc.get_session().context)

        m2m_view = listgrid.List(name, model, view, ids,limit=20, editable=True, m2m=1)
        m2m_view = ustr(m2m_view.render())
        return dict(m2m_view = m2m_view)