OPENERP 构建动态视图

来自:http://shine-it.net/index.php/topic,16142.0.html

在openerp展示界面通常是通过定义class的view(xml文件)来实现的。
有时这种方法不能支持用户自定义字段的需求,于是就可以通过重写fields_view_get()、 read()来实现。
实例代码

# -*- coding: utf-8 -*-
from openerp.osv import osv,fields
from lxml import etree
from openerp import tools
from openerp.tools import to_xml

class AnalysisQuestionnaireType(osv.osv):
    _name = ‘analysis.questionnaire.type‘
    _description = ‘问卷类型‘
    _columns = {
        ‘name‘: fields.char(‘名称‘, size=125, required=True),
        ‘analysis_set‘: fields.many2many(‘analysis.title.set‘, id1=‘analysis_questionnaire_type_id‘,
                                         id2=‘analysis_title_set_id‘, string=‘主题‘),
    }

class AnalysisTitleSet(osv.osv):
    _name = "analysis.title.set"
    _description = "主题"
    _columns = {
        "name": fields.char(string="名称", size=125, required=True,),
        ‘analysis_questionnaire_type‘: fields.many2many(‘analysis.questionnaire.type‘,
                                                        id1=‘analysis_title_set_id‘,
                                                        id2=‘analysis_questionnaire_type_id‘,
                                                        string=‘问卷类型‘),
        "analysis_title": fields.one2many(‘analysis.title‘, ‘set‘, ‘题目‘),
    }

class AnalysisTitle(osv.osv):
    _name = "analysis.title"
    _description = "题目"
    _columns = {
        "name": fields.char(string="名称", size=125, required=True),
        "note": fields.text("描述"),
        "set": fields.many2one("analysis.title.set", string="主题", required=True),
        ‘type‘: fields.selection([(‘multiple_choice_only_one_ans‘, ‘单项选择‘),
                                  (‘multiple_choice_multiple_ans‘, ‘多项选择‘),
                                  (‘matrix_of_choices_only_one_ans‘, ‘单选组合‘),
                                  (‘single_textbox‘, ‘单行文本框‘),
                                  (‘multiple_textbox‘, ‘多个单行文本框‘),
                                  (‘comment‘, ‘多行文本框‘),
                                  (‘date‘, ‘日期框‘),
                                  (‘date_and_time‘, ‘日期时间框‘),
                                  (‘descriptive_text‘, ‘描述性文本‘),
                                  (‘attachment‘, ‘附件‘),
                                  (‘image‘, ‘图片‘),
                                  ], ‘题目类型‘,  required=1,),
        ‘is_require_answer‘: fields.boolean(‘必填项‘),
        ‘option_id‘: fields.one2many(‘analysis.title.option‘, ‘title_id‘, ‘备选答案‘),
        ‘column_heading_ids‘: fields.one2many(‘analysis.title.column.heading‘, ‘title_id‘, ‘标题‘),
        ‘descriptive_text‘: fields.text(‘描述文本‘),
    }

class AnalysisTitleOption(osv.osv):
    _name = ‘analysis.title.option‘
    _description = ‘答案选项‘
    _columns = {
        ‘title_id‘: fields.many2one(‘analysis.title‘, ‘题目‘, ondelete=‘cascade‘),
        ‘option‘: fields.char(‘答案选项‘, size=128, required=True),
        ‘type‘: fields.selection([(‘char‘, ‘字符型‘),
                                 (‘date‘, ‘日期‘),
                                 (‘datetime‘, ‘日期时间型‘),
                                 (‘integer‘, ‘整数型‘),
                                 (‘float‘, ‘小数型‘),
                                 (‘selection‘, ‘选择型‘)],
                                 ‘答案类型‘,
                                 required=True),

    }

class AnalysisTitleColumnHeading(osv.osv):
    _name = ‘analysis.title.column.heading‘
    _description = ‘选项标题‘
    _columns = {
        ‘name‘: fields.char(‘选项标题‘, size=128, required=True),
        ‘title_id‘: fields.many2one(‘analysis.title‘, ‘题目‘, ondelete=‘cascade‘),
    }

class AnalysisAnswer(osv.osv):
    _name = ‘analysis.answer‘
    _description = ‘答案‘
    _columns = {
        ‘analysis_questionnaire‘: fields.many2one(‘analysis.questionnaire‘, ‘问卷‘),
        ‘value‘: fields.text(‘值‘)
    }

class AnalysisQuestionnaire(osv.osv):
    _name = ‘analysis.questionnaire‘
    _description = ‘分析问卷‘

    _columns = {
        "name": fields.char(string=‘名称‘, size=125, required=True),
        ‘type‘: fields.many2one(‘analysis.questionnaire.type‘, string=‘类型‘, required=True),
        ‘title‘: fields.one2many(‘analysis.answer‘, "analysis_questionnaire", "答案"),
    }

    def default_get(self, cr, uid, fields_list, context=None):
        default = super(AnalysisQuestionnaire, self).default_get(cr, uid, fields_list, context=context)
        con = context.get(‘type‘)
        default[‘type‘] = con
        return default

    def view_init(self, cr, uid, fields_list, context=None):
        pass

    def fields_view_get(self, cr, uid, view_id=None, view_type=‘form‘, context=None, toolbar=False, submenu=False,):
        if context is None:
            context = {}
        result = super(AnalysisQuestionnaire, self).fields_view_get(cr, uid, view_id,
                                                                    view_type=view_type, context=context,
                                                                    toolbar=toolbar, submenu=submenu)
        if view_type == ‘form‘ and context.has_key(‘type‘):
            view = etree.fromstring(result[‘arch‘])
            fields = result[‘fields‘]
            print etree.tostring(view)
            notebook = etree.SubElement(view, ‘notebook‘)
            sets = self.pool.get(‘analysis.questionnaire.type‘).browse(cr, uid, context[‘type‘]).analysis_set
            q_no = 0
            for set in sets:
                page = etree.SubElement(notebook, ‘page‘, string=set.name)
                for title in set.analysis_title:
                    q_no += 1
                    etree.SubElement(page, ‘newline‘)
                    if title.is_require_answer:
                        etree.SubElement(page, ‘separator‘, {‘string‘: ‘*‘+tools.ustr(q_no)+‘.‘+tools.ustr(title.name)})
                    else:
                        etree.SubElement(page, ‘separator‘, {‘string‘: tools.ustr(q_no)+‘.‘+tools.ustr(title.name)})

                    if title.type == ‘multiple_choice_only_one_ans‘:
                        parent = etree.SubElement(page, ‘group‘)
                        selection = []
                        for option in title.option_id:
                            selection.append((tools.ustr(option.id), option.option))
                        fields[‘title‘+‘_‘+tools.ustr(title.id)+‘_selection‘] = {‘type‘: ‘selection‘,
                                                                                 ‘selection‘: selection,
                                                                                 ‘name‘: title.name}
                        etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘_selection‘})
                    elif title.type == ‘multiple_choice_multiple_ans‘:
                        parent = etree.SubElement(page, ‘group‘, {‘col‘: ‘4‘, ‘colspan‘: ‘4‘})
                        for option in title.option_id:
                            etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘option‘+‘_‘
                                                                       + tools.ustr(option.id)})
                            fields[‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘option‘+‘_‘
                                   + tools.ustr(option.id)] = {‘type‘: ‘boolean‘, ‘string‘: option.option}
                    elif title.type == ‘matrix_of_choices_only_one_ans‘:
                        parent = etree.SubElement(page, ‘group‘, {‘col‘: ‘2‘, ‘colspan‘: ‘2‘})
                        selection = []
                        for option in title.option_id:
                            selection.append((tools.ustr(option.id), option.option))
                        for col in title.column_heading_ids:
                            etree.SubElement(parent, ‘newline‘)
                            etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘
                                                                       + tools.ustr(col.id),
                                                               })
                            fields[‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘
                                   + tools.ustr(col.id)] = {‘type‘: ‘selection‘, ‘selection‘: selection}
                    elif title.type == ‘single_textbox‘:
                        parent = etree.SubElement(page, ‘group‘,)
                        etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id) + "_single",
                                                           ‘nolabel‘: "1",
                                                           ‘colspan‘: "4"})
                        fields[‘title‘+‘_‘+tools.ustr(title.id) + "_single"] = {‘type‘: ‘char‘, ‘size‘: 255}
                    elif title.type == ‘multiple_textbox‘:
                        parent = etree.SubElement(page, ‘group‘, {‘col‘: ‘4‘, ‘colspan‘: ‘4‘})
                        for col in title.column_heading_ids:
                            fields[‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘+tools.ustr(col.id)] = {‘type‘: ‘char‘,
                                                                                                         ‘size‘: 255}
                            etree.SubElement(parent, ‘field‘, {‘width‘: ‘300‘,
                                                               ‘colspan‘: ‘1‘,
                                                               ‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘
                                                                       + tools.ustr(col.id)})
                    elif title.type == ‘comment‘:
                        parent = etree.SubElement(page, ‘group‘)
                        etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id) + "_comment",
                                                           ‘nolabel‘: "1",
                                                           ‘colspan‘: "4"})
                        fields[‘title‘+‘_‘+tools.ustr(title.id) + "_comment"] = {‘type‘: ‘text‘}
                    elif title.type == ‘date‘:
                        parent = etree.SubElement(page, ‘group‘, {‘col‘: ‘4‘, ‘colspan‘: ‘4‘})
                        for col in title.column_heading_ids:
                            fields[‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘+tools.ustr(col.id)] = {‘type‘: ‘date‘}
                            etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘
                                                                       + tools.ustr(col.id)})
                    elif title.type == ‘date_and_time‘:
                        parent = etree.SubElement(page, ‘group‘, {‘col‘: ‘4‘, ‘colspan‘: ‘4‘})
                        for col in title.column_heading_ids:
                            fields[‘title‘+‘_‘+tools.ustr(title.id)+‘-‘
                                   + ‘col‘+‘_‘+tools.ustr(col.id)] = {‘type‘: ‘datetime‘}
                            etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘-‘+‘col‘+‘_‘
                                                                       + tools.ustr(col.id)})
                    elif title.type == ‘attachment‘:
                        parent = etree.SubElement(page, ‘group‘,)
                        fields[‘title‘+‘_‘+tools.ustr(title.id)+‘_attachment‘] = {‘type‘: ‘binary‘}
                        etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘_attachment‘})
                    elif title.type == ‘descriptive_text‘:
                        parent = etree.SubElement(page, ‘group‘)
                        if title.descriptive_text:
                            for que_test in title.descriptive_text.split(‘\n‘):
                                etree.SubElement(parent, ‘label‘, {‘string‘: to_xml(tools.ustr(que_test)),
                                                                   ‘align‘: "0.0"})
                    elif title.type == ‘image‘:
                        parent = etree.SubElement(page, ‘group‘,)
                        fields[‘title‘+‘_‘+tools.ustr(title.id)+‘_image‘] = {‘type‘: ‘binary‘}
                        etree.SubElement(parent, ‘field‘, {‘name‘: ‘title‘+‘_‘+tools.ustr(title.id)+‘_image‘,
                                                           ‘widget‘: ‘image‘})
            result[‘arch‘] = etree.tostring(view)
        return result

    def create(self, cr, uid, vals, context=None):
        answer_obj = self.pool.get("analysis.answer")
        questionnaire_vals = {‘name‘: vals.get(‘name‘), ‘type‘: vals.get(‘type‘)}
        vals.pop(‘name‘, "not name")
        vals.pop(‘type‘, ‘not type‘)
        answer_vals = {}
        questionnaire_id = super(AnalysisQuestionnaire, self).create(cr, uid, questionnaire_vals, context=context)
        answer_vals[‘analysis_questionnaire‘] = questionnaire_id
        answer_vals[‘value‘] = vals
        answer_obj.create(cr, uid, answer_vals, context=context)
        return questionnaire_id

    def read(self, cr, user, ids, fields=None, context=None, load=‘_classic_read‘):
        result = super(AnalysisQuestionnaire, self).read(cr, user, ids, fields=fields, context=context, load=load)
        answer_obj = self.pool.get(‘analysis.answer‘)
        i = 0
        while i < len(result):
            answer_list = answer_obj.search(cr, user, [(‘analysis_questionnaire‘, ‘=‘, result[‘id‘])])
            if answer_list:
                val = eval(answer_obj.read(cr, user, answer_list, [‘value‘], context=context)[0][‘value‘])
                result.update(val)
            i += 1
        return result
上述代码用户可以自己定义问卷题目及题目类型。通过fields_view_get()画出view,然后把动态构建的字段及其值通过重写create() 把数据存储到另外一个表里。这里用的是一个text字段把create返回的值直接存储起来的。当需要查看保存过的数据时,通过重写read()整理成需要的数据格式返回。

OPENERP 构建动态视图

时间: 2024-10-30 13:33:58

OPENERP 构建动态视图的相关文章

openerp创建动态视图-fields_view_get

openerp的视图结构是以XML的格式存放于ir.ui.view表中,属于静态格式,设计之后就固定, 但可以通过在model中重写fields_view_get函数,在视图加载时修改arch属性,动态修改视图的结构 def fields_view_get(self, cr, uid, view_id=None,view_type='form',context=None,toolbar=False,submenu=False): ip_obj = self.pool.get('hr.rule.i

Struts2 动态视图(注解)

Struts2是一款优秀的MVC框架,支持多种视图类型,通过绑定值到视图.本文以代码的形式,介绍动态视图. Struts2配置Action有注解和XML方式,在这里使用注解方式. 一般的写法     @Action(value = "index", results = {@Result(name = SUCCESS, location = "index.jsp")})     public String index() {         return SUCCES

oracle动态视图v$,v_$,gv$,gv_$与x$之间的关系

前言:在oracle运维的过程中,经常会使用到一些以V$开头的动态视图,比如V$session, 有一次偶然看到有人用V_$session, 初以为别人写错了,没想到desc v_$session以后能看到和v$session一样的结构,再以后又发现以gv$开头的视图等等.趁这次在一台Linux系统上装oracle的机会,终于弄清楚了这些动态视图与相应表之间的关系.这些都是由oracle自己管理的数据结构,得从v$fixed_table入手:[[email protected] admin]$

Android学习路线(二十)运用Fragment构建动态UI

要在Android系统上创建一个动态或者多面板的用户界面,你需要将UI组件以及activity行为封装成模块,让它能够在你的activity中灵活地切换显示与隐藏.你可以使用Fragment类来创建这些模块,它们能够表现得有些像嵌套的activity,它们定义着自己的布局,管理自己的生命周期. 当一个fragment指定了它自己的布局,它可以在activity中和其他的fragment配置为不同的组合,这样就能够为不同的屏幕尺寸来修改你的布局配置(在小屏幕上一次展现一个fragment,而在大屏

Android学习路线(二十一)运用Fragment构建动态UI——创建一个Fragment

你可以把fragment看成是activity的模块化部分,它拥有自己的生命周期,接受它自己的输入事件,你可以在activity运行时添加或者删除它(有点像是一个"子activity",你可以在不同的activity中重用它).本课将向你展示如何使用Support Libaray继承 Fragment 类来让你的应用能够兼容正在运行Android 1.6的设备. 提示: 如果你决定你的应用需求的最低API级别是11或者更高,那么你不需要使用Support Library,你可以直接使用

[转]C语言构建动态数组完整实例

原文地址:http://www.jb51.net/article/52153.htm 本文以一个完整的实例代码简述了C语言构建动态数组的方法,供大家参考,完整实例如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <malloc.h> int main(void) {     int len;     int * arr;     printf("请输入数组长度:&q

Android学习路线(二十二)运用Fragment构建动态UI——构建一个灵活的UI

先占个位置,下次翻译 :p When designing your application to support a wide range of screen sizes, you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space. For example, on a handset devi

Android学习路线(二十三)运用Fragment构建动态UI——Fragment间通讯

先占个位置,下次翻译 :p In order to reuse the Fragment UI components, you should build each as a completely self-contained, modular component that defines its own layout and behavior. Once you have defined these reusable Fragments, you can associate them with

使用Expression Tree构建动态LINQ查询

这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给的一个解决方案是采用Expression Tree来构建. 其实这个技术很早就有,在.NET Framework 3.5开始引入.之前也有不少同学写过很多不错的理论性文章.我自己当年学习这个,觉得最好的几篇文章是由"装配脑袋"同学写的.[有时间请仔细阅读这些入门指南,做点练习基本就能理解]