This question has been flagged
3 Replies
21508 Views

What would the view xml look like for a module that needed to use the same field more than once?

Explanatory example: you want to allow a phone number to be editable (like normal),

< field name="phone" />

but also want to do something like:

< field name="phone" widget="web_skypeButton" />

elsewhere on the page.

Whenever I include both, neither gets the value. Is there a better way of doing this?

Avatar
Discard
Author

A related field from the object to itself?

Best Answer

You must use a function field for this:

class your_class(osv.osv):

    _inherit = "your.class"

    def _your_function(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for id in ids:
            record = self.browse(cr, uid, id)
            res.update({id:record.phone})
        return res

    _columns = {
        'your_field' : fields.function(_your_function, type='char', size=32, method=True, store=False, multi=False),
        }

your_class()

and this is your view:

<record id="your_view" model="ir.ui.view">
            <field name="name">your.view.form</field>
            <field name="model">your.class</field>
            <field name="inherit_id" ref="original_module.original_form_view"/>
            <field name="arch" type="xml">
                <field name="phone" position="after">
                        <field name="your_field"/>
                </field>
            </field>
        </record>
Avatar
Discard
Author
  Thanks for that.   By record.phone I assume you meant record.your_field?

If so, I'm still confused by what the view would look like. This doesn't work for example:

   &lt;field name="arch" type="xml"&gt;
            &lt;field name="email" position="after"&gt;
                &lt;field name="your_field" string="Short code"/&gt;
            &lt;/field&gt;

            &lt;field name="your_field" position="after"&gt;
                &lt;field name="_your_function" string="Short code2"/&gt;
            &lt;/field&gt;
  &lt;/field&gt;


  and neither does:
Author
         &lt;field name="arch" type="xml"&gt;
            &lt;field name="email" position="after"&gt;
                &lt;field name="your_field" string="Short code"/&gt;
                &lt;field name="_your_function" string="Short code2"/&gt;
            &lt;/field&gt;
  &lt;/field&gt;

I edit the answer with right situation

Author

Thanks Francesco, but that view only contains one instance of the field, not two?

two. Phone is the original field and Your_Field is the second instance

Author

In my instance phone is NOT already on the view - I'm trying to display two fields - one as normal edit, one as a widget (see my sample code) . I used phone as an easy to understand example to demonstrate the use case, but I need to declare both. The first field is actually the edit field. The second is going to be rendered by a widget and display something different with that field.

I'm sorry but I can't explain in 500 charaters how to create a view for openerp module. All you need to know is that with the field function you can duplicate your original field content. I do assume that you already know how to create a view for an openerp module.

Author

Perhaps you could advise if this code is correct? http://pastebin.com/5TJx3d55

line 14 must be: res.update({id:record.mycol})

Author

That code is not quite correct (should be record.mycol) - but now have it working essentially in that both are being rendered ! Thank you. Now just need to work out how to include a xpath AND a normal "after" field at the same time...

Author

And the answer for anyone else looking, is to wrap in a <data> element.

Best Answer

I think you probably need a related field. Every time I've seen people put the same field on a form more than once, things don't work properly.

It much easier and probably faster than using functional fields as other answers suggested.

    _columns = {
        'phone': fields.integer('Phone'),
        'phone_2': fields.related('phone', string='Phone'),
    }

Avatar
Discard
Best Answer

You can define two field:

  • first - what you need
  • second - functional field, that return value from first field

This code for python:

class phone_example(osv.osv):
    _name = 'phone.example'

    def _get_phone(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for phone in self.browse(cr, uid, ids, context=context):
            res[phone.id] = phone.phone
        return res

    _columns = {
        'phone': fields.integer('Phone'),
        'phone_2': fields.function(_get_phone, method=True),
    }

Then you can use two field, that will show the same.

Note. Second field will show only data from DB. If you change first in form, second don't update while you don't save form. Use also onchange method for update second field realtime.

Avatar
Discard
Author

I'm very new to python - what would that second one look like in code please?