如何在openerp Web客户端中显示日志消息?

时间:2013-03-27 08:15:05

标签: logging openerp

我尝试在创建产品对象后显示消息,该产品对象告诉用户产品product.name创建成功 这是代码:

def log_prod(self, cr, uid, ids, context=None):
    product=self.pool.get('product.product').browse(cr, uid, ids)
    self.log(cr, uid, ids , _("Product %s has been created") % product.name , context=context)
    return True

def create(self, cr, uid, data, context=None):
    new_id = super(product_product,self).create(cr, uid, data, context)
    self.log_prod(cr,uid,new_id,context)
    return new_id



当我创造产品时,没有出现任何东西

但之后我尝试创建了一个收货,产品创建的日志消息出现了,如何在创建产品显示页面后显示日志消息?

5 个答案:

答案 0 :(得分:1)

我遇到过这个问题,但这种方式对我很有帮助,很棒: 来自link

创建一个模块来保存消息并以表格形式显示:

from osv import osv
from osv import fields
from openerp.tools.translate import _

WARNING_TYPES = [('warning','Warning'),('info','Information'),('error','Error')]

class warning(osv.osv_memory):
    _name = 'warning'
    _description = 'warning'
    _columns = {
        'type': fields.selection(WARNING_TYPES, string='Type', readonly=True),
        'title': fields.char(string="Title", size=100, readonly=True),
        'message': fields.text(string="Message", readonly=True)}
    _req_name = 'title'

    def _get_view_id(self, cr, uid):
        """Get the view id
        @return: view id, or False if no view found
        """
        res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'osc_integ', 'warning_form')
        return res and res[1] or False

    def message(self, cr, uid, id, context):
        message = self.browse(cr, uid, id)
        message_type = [t[1]for t in WARNING_TYPES if message.type == t[0]][0]
        print '%s: %s' % (_(message_type), _(message.title))
        res = {
            'name': '%s: %s' % (_(message_type), _(message.title)),
            'view_type': 'form', 
            'view_mode': 'form',
            'view_id': self._get_view_id(cr, uid),
            'res_model': 'warning',
            'domain': [],
            'context': context,
            'type': 'ir.actions.act_window',
            'target': 'new',
            'res_id': message.id
        }
        return res

    def warning(self, cr, uid, title, message, context=None):
        id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'warning'})
        res = self.message(cr, uid, id, context)
        return res

    def info(self, cr, uid, title, message, context=None):
        id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'info'})
        res = self.message(cr, uid, id, context)
        return res

    def error(self, cr, uid, title, message, context=None):
        id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'error'})
        res = self.message(cr, uid, id, context)
        return res

创建视图表单XML:

<openerp>
   <data>
        <record id="warning_form" model="ir.ui.view">
            <field name="name">warning.form</field>
            <field name="model">warning</field>
            <field eval="20" name="priority"/>
            <field name="arch" type="xml">
                <form string="Warning" version="7.0">
                    <field name="message"  nolabel="1" />
                    <footer>
                        <button string="OK" class="oe_highlight" special="cancel" />
                    </footer>
                </form>
            </field>
        </record>

        <record model="ir.actions.act_window" id="action_warning">
            <field name="name">Warning</field>
            <field name="res_model">warning</field>
            <field name="view_type">form</field>
            <field name="view_mode">form</field>
            <field name="view_id" ref="warning_form" />
            <field name="target">new</field>
        </record>
    </data>
</openerp>

最后,您可以随时调用方法:

return self.pool.get('warning').info(cr, uid, title='Export imformation', message="%s products Created, %s products Updated "%(str(prod_new),str(prod_update)))

答案 1 :(得分:0)

此AFAIK没有小部件。你应该发展自己的。您可以找到一个起点here

答案 2 :(得分:0)

def log_prod(self, cr, uid, ids, context=None):
        product=self.pool.get('product.product').browse(cr, uid, ids)
        msg=_("Product %s has been created") % product.name
        self.message_post(cr, uid, ids, body=msg, context=context)
        return True

def create(self, cr, uid, data, context=None):
    new_id = super(product_product,self).create(cr, uid, data, context)
    self.log_prod(cr,uid,new_id,context)
    return new_id

喜欢这段代码试试。

希望这会对你有所帮助。 :)

答案 3 :(得分:0)

def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
                        subtype=None, parent_id=False, attachments=None, context=None,
                        content_subtype='html', **kwargs):
        """ Post a new message in an existing thread, returning the new
            mail.message ID.
        :param int thread_id: thread ID to post into, or list with one ID;
            if False/0, mail.message model will also be set as False
        :param str body: body of the message, usually raw HTML that will
            be sanitized
        :param str type: see mail_message.type field
        :param str content_subtype:: if plaintext: convert body into html
        :param int parent_id: handle reply to a previous message by adding the
            parent partners to the message in case of private discussion
        :param tuple(str,str) attachments or list id: list of attachment tuples in the form
            ``(name,content)``, where content is NOT base64 encoded

        Extra keyword arguments will be used as default column values for the
        new mail.message record. Special cases:
            - attachment_ids: supposed not attached to any document; attach them
                to the related document. Should only be set by Chatter.
        :return int: ID of newly created mail.message
    """
    if context is None:
        context = {}
    if attachments is None:
        attachments = {}
    mail_message = self.pool.get('mail.message')
    ir_attachment = self.pool.get('ir.attachment')

    assert (not thread_id) or \
            isinstance(thread_id, (int, long)) or \
            (isinstance(thread_id, (list, tuple)) and len(thread_id) == 1), \
            "Invalid thread_id; should be 0, False, an ID or a list with one ID"
    if isinstance(thread_id, (list, tuple)):
        thread_id = thread_id[0]

    # if we're processing a message directly coming from the gateway, the destination model was
    # set in the context.
    model = False
    if thread_id:
        model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name
        if model != self._name:
            del context['thread_model']
            return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)

    # 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails
    email_from = kwargs.get('email_from')
    if email_from and thread_id and type == 'email' and kwargs.get('author_id'):
        email_list = tools.email_split(email_from)
        doc = self.browse(cr, uid, thread_id, context=context)
        if email_list and doc:
            author_ids = self.pool.get('res.partner').search(cr, uid, [
                                    ('email', 'ilike', email_list[0]),
                                    ('id', 'in', [f.id for f in doc.message_follower_ids])
                                ], limit=1, context=context)
            if author_ids:
                kwargs['author_id'] = author_ids[0]
    author_id = kwargs.get('author_id')
    if author_id is None:  # keep False values
        author_id = self.pool.get('mail.message')._get_default_author(cr, uid, context=context)

    # 1: Handle content subtype: if plaintext, converto into HTML
    if content_subtype == 'plaintext':
        body = tools.plaintext2html(body)

    # 2: Private message: add recipients (recipients and author of parent message) - current author
    #   + legacy-code management (! we manage only 4 and 6 commands)
    partner_ids = set()
    kwargs_partner_ids = kwargs.pop('partner_ids', [])
    for partner_id in kwargs_partner_ids:
        if isinstance(partner_id, (list, tuple)) and partner_id[0] == 4 and len(partner_id) == 2:
            partner_ids.add(partner_id[1])
        if isinstance(partner_id, (list, tuple)) and partner_id[0] == 6 and len(partner_id) == 3:
            partner_ids |= set(partner_id[2])
        elif isinstance(partner_id, (int, long)):
            partner_ids.add(partner_id)
        else:
            pass  # we do not manage anything else
    if parent_id and not model:
        parent_message = mail_message.browse(cr, uid, parent_id, context=context)
        private_followers = set([partner.id for partner in parent_message.partner_ids])
        if parent_message.author_id:
            private_followers.add(parent_message.author_id.id)
        private_followers -= set([author_id])
        partner_ids |= private_followers

    # 3. Attachments
    #   - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
    attachment_ids = kwargs.pop('attachment_ids', []) or []  # because we could receive None (some old code sends None)
    if attachment_ids:
        filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
            ('res_model', '=', 'mail.compose.message'),
            ('res_id', '=', 0),
            ('create_uid', '=', uid),
            ('id', 'in', attachment_ids)], context=context)
        if filtered_attachment_ids:
            ir_attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context)
    attachment_ids = [(4, id) for id in attachment_ids]
    # Handle attachments parameter, that is a dictionary of attachments
    for name, content in attachments:
        if isinstance(content, unicode):
            content = content.encode('utf-8')
        data_attach = {
            'name': name,
            'datas': base64.b64encode(str(content)),
            'datas_fname': name,
            'description': name,
            'res_model': model,
            'res_id': thread_id,
        }
        attachment_ids.append((0, 0, data_attach))

    # 4: mail.message.subtype
    subtype_id = False
    if subtype:
        if '.' not in subtype:
            subtype = 'mail.%s' % subtype
        ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, *subtype.split('.'))
        subtype_id = ref and ref[1] or False

    # automatically subscribe recipients if asked to
    if context.get('mail_post_autofollow') and thread_id and partner_ids:
        partner_to_subscribe = partner_ids
        if context.get('mail_post_autofollow_partner_ids'):
            partner_to_subscribe = filter(lambda item: item in context.get('mail_post_autofollow_partner_ids'), partner_ids)
        self.message_subscribe(cr, uid, [thread_id], list(partner_to_subscribe), context=context)

    # _mail_flat_thread: automatically set free messages to the first posted message
    if self._mail_flat_thread and not parent_id and thread_id:
        message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model)], context=context, order="id ASC", limit=1)
        parent_id = message_ids and message_ids[0] or False
    # we want to set a parent: force to set the parent_id to the oldest ancestor, to avoid having more than 1 level of thread
    elif parent_id:
        message_ids = mail_message.search(cr, SUPERUSER_ID, [('id', '=', parent_id), ('parent_id', '!=', False)], context=context)
        # avoid loops when finding ancestors
        processed_list = []
        if message_ids:
            message = mail_message.browse(cr, SUPERUSER_ID, message_ids[0], context=context)
            while (message.parent_id and message.parent_id.id not in processed_list):
                processed_list.append(message.parent_id.id)
                message = message.parent_id
            parent_id = message.id

    values = kwargs
    values.update({
        'author_id': author_id,
        'model': model,
        'res_id': thread_id or False,
        'body': body,
        'subject': subject or False,
        'type': type,
        'parent_id': parent_id,
        'attachment_ids': attachment_ids,
        'subtype_id': subtype_id,
        'partner_ids': [(4, pid) for pid in partner_ids],
    })

    # Avoid warnings about non-existing fields
    for x in ('from', 'to', 'cc'):
        values.pop(x, None)

    # Create and auto subscribe the author
    msg_id = mail_message.create(cr, uid, values, context=context)
    message = mail_message.browse(cr, uid, msg_id, context=context)
    if message.author_id and thread_id and type != 'notification' and not context.get('mail_create_nosubscribe'):
        self.message_subscribe(cr, uid, [thread_id], [message.author_id.id], context=context)
    return msg_id

答案 4 :(得分:0)

在我看来,最简单的方法是使用“action_info”或“action_warn”客户端操作。它们都产生类似Growl的通知,但它们使用不同的图标。要调用其中任何一个,请从服务器操作返回字典,如下所示:

{
    'type': 'ir.actions.client',
    'tag': 'action_info',
    'name': 'Notification',
    'params': {
       'title': 'Notification Title',
       'text': 'Notification text.',
       'sticky': True
    }
}

sticky参数外,大部分内容都应该是不言自明的。 sticky表示通知是否应保留,直到用户解除通知。如果它被设置为False,它会在几秒后自行消失。

如果你需要的话,有一个更为全面的例子on my blog