1
votes

Hallo I override name_get in a custom many2one field in partner_view, to show a different field than name, according to context

class partner_relation_role(osv.osv):

_name = "partner.relation.role"
_description = 'Types of relationships between contacts'

_columns = {
    'name': fields.char('Nome', size=128, required=True),
    'description': fields.text('Description'),
    'name_parent': fields.char('Parent name'),
    'name_child': fields.char('Child name'),
}

def name_get(self, cr, uid, ids, context=None):
    if context is None:
        context = {}

    res = []
    ret_name = ""

    for object in self.browse(cr, uid, ids, context = context):

        if object.name:
            if  context.get('parent_relation') is None:
                ret_name = object.name or ""
            elif context.get('parent_relation') is True:
                # returns relation name for parent relation
                ret_name = object.name_parent or object.name
            elif context.get('parent_relation') is False:
                ret_name = object.name_child or object.name

        res.append((object.id,ret_name))

    return res

And in the res.partner inherited view:

<xpath expr="//page[@string='Contacts']" position="after">
                <page name="uprelations" string="Relationships">
                    <field name="uprelation_ids" nolabel="1" context="{'default_partner_id': active_id}">
                        <tree editable="bottom">
                            <field name="related_partner_id" options="{'no_create': True}"/>
                            <field name="role_id" options="{'no_create': True}" context="{'parent_relation' : True}"/>
                            <field name="influence"/>
                        </tree>
                    </field>
                </page>
                <page name="downrelations" string="Has relations from">
                    <field name="downrelation_ids" nolabel="1" context="{'default_related_partner_id': active_id}">
                        <tree editable="bottom">
                            <field name="partner_id" options="{'no_create': True}"/>
                            <field name="role_id" options="{'no_create': True}" context="{'parent_relation' : False}" />
                            <field name="influence"/>
                        </tree>
                    </field>
                </page>
            </xpath>

This works when I'm editing the record. When I save it, the "name" is shown, not the other field value.

UPDATE According to the helpful Adrian Merrall, being this used in a view I should put the context in the view action: but in this case the same action opens a view having two pages with different context (page 1 with context variable = TRUE, page 2 with same variable = FALSE). Where should I put this context?

UPDATE2 I rethinking the whole logic. Should I use a different fields.related for each page? The aim is to relate contacts and to show the different relationship "versus" (uprelation: A is attorney for B, downrelation: B is represented by A; A has consultancy from C, C is consultant for A). Each relationship has two versus, and two peers: the peer from whom the uprelation starts is the "master" or "parent", and the other one is the "slave" or "child". The same contact can be master for some relationships and slave for others.

2

2 Answers

1
votes

On the surface your code looks OK but of course you need to check that you are getting what you expect in your context. If this is a view then you will need to set your context in the window action.

One tiny problem is your reuse of ret_name. You initialise it to an empty string but then re-use it inside your loop. If your first object record has a name then ret_name will be changed to a new value. Any subsequent records that do not have a name will not use the empty string, but whatever value ret_name was reassigned to. Remember that unlike java, python does not have a loop scope. The same thing will happen if parent_relation is in the context but has a value other than None, True or False.

Finally, you should declare context as a named parameter in the browse and just call the browse in the loop as:

for object in self.browse(cr, uid, ids, context = context):
0
votes

I solved, the code was OK: I moved the context upward to the page. The resulting view is:

<page name="downrelations" string="In relazione con">
                    <field name="downrelation_ids" nolabel="1" context="{'default_related_partner_id': active_id, 'parent_relation' : False}">
                        <tree string="Altri contatti in relazione" editable="bottom">
                            <field name="partner_id" options="{'no_create': True}"/>
                            <field name="role_id" options="{'no_create': True}" context="{'parent_relation' : False}" />
                            <field name="influence"/>
                        </tree>
                    </field>
                </page>

Thank you Adrian for the hints.