Odoo: get type of field by name - odoo

in odoo you can get value of field by it's str name:
exm:
name = getattr(self, 'name')
what i want now is to know the type of field name is it :
fields.Char, fields.Many2one, fields.Many2many .....
so what i need is something like this
gettype(self, 'user_id')
is there a way to now what is the type of field in odoo?

You can search from ir.model.fields model.
ir_model_obj=self.env['ir.model.fields']
ir_model_field=ir_model_obj.search([('model','=',model),('name','=',field)])
field_type=ir_model_field.ttype
if field_type=='many2one':
print "do operation"
This may help you.

Odoo provides this information in the _fields attribute, I think It's better because every thing happens In the Python side no need for contacting the database, especially In my case my model have more than 30 fields :
for name, field in self._fields.iteritems():
if not isinstance(field, (fields.Many2one, fields.Many2many, fields.One2many)):
# logic go here
If you you want to verify just one fields:
if not isinstance(self._fields[field_name], (fields.Many2one, ...)): # do something

Related

Odoo: how to set default field for many2many field by id?

i want to set default value in many2many field for example:
that field in models.py:
# alarms
alarm_ids = fields.Many2many(
'calendar.alarm', 'calendar_alarm_calendar_event_rel',
string='Reminders', ondelete="restrict",
help="Notifications sent to all attendees to remind of the meeting.")
also it is default values created by system, and i want first variant by default:
i know that i can set it by id, but dont know how.
You can use Command to set X2many field values.
From the documentation:
Via Python, we encourage developers craft new commands via the various functions of this namespace. We also encourage developers to use the command identifier constant names when comparing the 1st element of existing commands.
Example:
from odoo import Command, models, fields
class CalendarEvent(models.Model):
_inherit = 'calendar.event'
alarm_ids = fields.Many2many(default=lambda self: [Command.link(self.env.ref('calendar.alarm_notif_1').id)])
i just watch in postgres, there is no id`s like in xml screenshots, i just take id of a record and find some documentation.
next example works:

Table name is too long odoo 13

I am getting this error after adding a binary filed I remover the filed but getting the same error
Table name 'n_hesaby_subscription_manager_subscription_manager_res_users_rel' is too long
odoo.exceptions.ValidationError: ("Table name 'n_hesaby_subscription_manager_subscription_manager_res_users_rel' is too long", None) - - -
does anyone know what it means, I can't find it
From the look of the table name it's created from a many2many field between n_hesaby_subscription_manager_subscription_manager and res.users when you don't provide a name for the relation table Odoo will generate it for you model_1_name_model_2_name_rel.
So in your many2many definition specify a shorter name
m2m_field_name = fields.Many2many(comodel_name='res.users',
relation='put_nice_table_name_here',
column1='put_nice_and_short_field_name_here_to',
column2='user_id',
string='You field label')
I'm using my phone sorry for my short answer I hope you get the idea, you can check Odoo standard modules you will find planty of examples.
Always specify the name of the relation in your many2many field is a good practice prevent unexpected behavior.

How to fill a field by date now from a click of a button

I want to fill a field by date now from a click of a button of the action
class sale_inheritd(models.Model):
_inherit = 'sale.order'
#api.multi
def action_sale_temporary(self):
for order in self:
self.env['project.project'].search([('project_id', '=', 'related_project_id')]).write({'temporary_reception_date':datetime.date.today()})
order.write({'state': 'temporary'})
What is the problem with this function?
I didn't understand the domain that you have passed to search method but if you want to fill a field with type Date:
.write({'temporary_reception_date':fields.Date.today()})
and for Datetime field:
.write({'temporary_reception_date':fields.Datetime.now()})
Note: and don't use self to access a field inside the loop exm: self.related_project_id use order.related_project_id instead or you most likely will have Singleton Error
EDITS: as #CZoellner said it's better to fields.Date.context_today(self) because that will prevent problems with user timezones
From your question it is not clear what are you trying to accomplish.
Your search method you search for project_id[looks like many2one field] equals to a string.
If it is many2one field then pass id to get correct result.
Also make sure self.env['project.project'].search([('project_id', '=', 'related_project_id')]) returns a single record only else it will lead to singleton error.
If there is only one record returned by search method then there is no issue in writing to the record like you did.

Add field/string length to logstash event

I'm trying to add a string length field to an index. Ideally, I'd like to use the kibana script feature as I can 'add' this field later but I keep getting a null_pointer_exception with the following code... I'm trying to sort in a visualization based on the fields length.
doc['field'].value ? doc['field'].length() : 0
Is this correct?
I thought it was because my field isn't always set (sparse data), but I added the ?:0 to combat that (which didn't work)
Any ideas?
You can define an scripted field in Kibana, of type int, language painless, and try this:
return (doc['field'].value != null? doc['field'].value.length(): 0);

How to get name fields exist of model in Odoo(OpenERP)?

Please, help me. I have a model 'res.users'. I want to get name fields exist(declared) in my model. What should I do? Thanks.
You question is not much clear what you want to do with that, but if you want to get the name of the model then you should go for below answer.
It's good if you can elaborate your question with output or few more details.
you should try following,
model = self.env['ir.model'].search([('model','=','res.users')])
if model:
print model.name
However you can access all the fields of that model. There is field_id (one2many) field is there in ir.model.
As I understand your question, I think you want to check the name field exists in values or not.
So, while you write any method you can check it with a small block of code.
Like:
if 'name' in vals:
"You block of CODE"
If I understood correctly you would like to know what field is considered as the name field (as it could be modified using _rec_name when declaring the class). I think that you just need to check ._rec_name, based on this piece of code of models.py that do the opposite:
# validate rec_name
if cls._rec_name:
assert cls._rec_name in cls._fields, \
"Invalid rec_name %s for model %s" % (cls._rec_name, cls._name)
elif 'name' in cls._fields:
cls._rec_name = 'name'
elif 'x_name' in cls._fields:
cls._rec_name = 'x_name'