I want to extend the "state" column of the mrp.production model. There was an example I found in https://www.odoo.com/de_DE/forum/how-to/developers-13/how-to-extend-fields-selection-options-without-overwriting-them-21529 but it seems to not work in odoo 11.
i.e. the __init__ signature changed to __init__(self, pool, cr) (guessing this from the error trace that I saw referencing model.__init__(pool, cr))
from odoo import models, fields
import logging
_logger = logging.getLogger(__name__)
class mrp_production(models.Model):
_inherit = 'mrp.production'
def __init__(self, pool, cr):
super(mrp_production, self).__init__(pool, cr)
states = self._columns['state'].Selection
_logger.debug('extend state of mrp.production')
state_other = ('other_state', 'My State')
if state_other not in states:
states.append(state_other)
The Error I'm receiving is:
AttributeError: 'mrp.production' object has no attribute '_columns'
You don't need to extend the __init__. Please look into the documentation to get a first look how to extend odoo business models.
For your example the correct code:
from odoo import models, fields
class MrpProduction(models.Model):
_inherit = 'mrp.production'
state = fields.Selection(
selection_add=[('other_state', 'My State')])
The tutorial you follow is for old API.
You can try
https://www.odoo.yenthevg.com/extend-selection-odoo-10/
from odoo import models, fields, api, _
class HrEmployee(models.Model):
_inherit = 'hr.employee'
gender = fields.Selection(selection_add=[('transgender', 'Transgender')])
Related
I would like to know if it's possible or not to call an Odoo studio field in a model like this ?
class sale_order(models.Model):
_inherit = "sale.order"
#api.onchange('x_studio_first_field')
def _onchange_firstfield(self):
if self.x_studio_first_field:
self.x_studio_second_field = self.x_studio_first_field
Thanks by advance
Apparently, the answer is what i've write in exemple. I tried it and it works !
class sale_order(models.Model):
_inherit = "sale.order"
#api.onchange('x_studio_first_field')
def _onchange_firstfield(self):
if self.x_studio_first_field:
self.x_studio_second_field = self.x_studio_first_field
I want to get hobbys according to log in user but I am always getting
TypeError at /backend/api/hobbys/
init() takes 1 positional argument but 2 were given
this is my views.py
class ListCreateHobbyView(GenericAPIView):
queryset = Hobby.objects.all()
serializer_class = HobbySerializer
# Filtering by logged in user
def get(self, request, *args, **kwargs):
queryset = Hobby.objects.filter(user=request.user)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
What can be wrong?
Please do not override the entire .get(…) method. This means that (nearly) all boilerplate code that Django has written is no longer applied. You filter in the .get_queryset(…) method [drf-doc]:
from rest_framework.generics import ListAPIView
class ListCreateHobbyView(ListAPIView):
queryset = Hobby.objects.all()
serializer_class = HobbySerializer
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
user=self.request.user
)
You can also make a custom filter backend: this is a reusable component that you then can use in other views. This thus looks like:
from rest_framework import filters
class UserFilterBackend(filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
return queryset.filter(user=request.user)
then you use this as filter backend:
from rest_framework.generics import ListAPIView
class ListCreateHobbyView(ListAPIView):
queryset = Hobby.objects.all()
serializer_class = HobbySerializer
filter_backends = [UserFilterBackend]
The advantage of this approach is that if you later construct extra views that need the same filtering, you can simply "plug" these in.
I am trying to add a new field in the model of SaleOrderLine (Official Sale module).
It works perfect with the old API:
from openerp import _
from openerp.osv import osv, fields
class SaleOrderLineExt(osv.osv):
_inherit = ['sale.order.line']
_columns = {
'my_field_code': fields.float(string='My field Code'),
}
But, If I try to use the new API, the field is not created in the database.
from openerp import api, fields, models, _
class SaleOrderLineExt(models.Model):
_inherit = ['sale.order.line']
my_field_code = fields.Float(string='My field Code'),
I have read the Odoo new API guideline and it appears that my code is right, but it is not working.
What am I doing wrong?
Try with following code.
from openerp import api, fields, models, _
class SaleOrderLineExt(models.Model):
_inherit = 'sale.order.line'
my_field_code = fields.Float(string='My field Code')
Remove , at the end of field declaration.
Just Remove the semicolon which is at the end of field. You code will definitely work.
I have a custom module called admission form with some fields suppose name, phone, email, etc. how to add this form to website module using templatr to work like contact form in contact us page when filled data is automatically created in new leads. instead of leads i want it to transfer the information to my custom module.
Summary: instruction to relate website to custom module.
class AdmissionForm(models.Model):
_name = 'admission.form'
name = fields.Char()
phone = fields.Integer()
email = fields.Char()
faculty = field.Many2one('res.faculty')
In ODOO Whenever you want to performe some task at the time of creation ,then you must override create method in your model (:admission.form).
Let say you want to create a partner just after creation of the record in admission.form model then follow these steps:
Override create method .
Call the super with the argument and hold it value in result.
Now do your task .
return result.
Code snippet:
#api.model
def create(self, vals):
result = super(AdmissionForm, self).create(vals)
new_vals = dict(name=result.name,
phone=result.phone,
email=result.email,
is_company=1,
supplier=1,
customer=1,
)
self.env['res.partner'].create(new_vals)
return result
In case if you want to do some task before creation of record then follow these steps:
Override create method .
Do your task .
Call the super with the argument and return it.
#api.model
def create(self, vals):
new_vals = dict(name=vals.get('name'),
phone=vals.get('phone'),
email=vals.get('email'),
is_company=1,
supplier=1,
customer=1,
)
partner=self.env['res.partner'].create(new_vals)
return super(AdmissionForm, self).create(vals)
I need to add the following class method to my existing pipeline
http://doc.scrapy.org/en/latest/faq.html#i-m-getting-an-error-cannot-import-name-crawler
i am not sure how to have 2 of these class methods in my class
from twisted.enterprise import adbapi
import MySQLdb.cursors
class MySQLStorePipeline(object):
"""A pipeline to store the item in a MySQL database.
This implementation uses Twisted's asynchronous database API.
"""
def __init__(self, dbpool):
self.dbpool = dbpool
#classmethod
def from_settings(cls, settings):
dbargs = dict(
host= settings['DB_HOST'],
db= settings['DB_NAME'],
user= settings['DB_USER'],
passwd= settings['DB_PASSWD'],
charset='utf8',
use_unicode=True,
)
dbpool = adbapi.ConnectionPool('MySQLdb', **dbargs)
return cls(dbpool)
def process_item(self, item, spider):
pass
From my understanding of class methods, several class methods in a python class should just be fine. It just depends on which one the caller requires. However, I have only seen from_crawler until now in scrapy pipelines. From there you can get access to the settings via crawler.settings
Are you sure that from_settings is required? I did not check all occurences, but in middleware.py priority seems to apply: If a crawler object is available and a from_crawler method exists, this is taken. Otherwise, if there is a from_settings method, that is taken. Otherwise, the raw constructor is taken.
if crawler and hasattr(mwcls, 'from_crawler'):
mw = mwcls.from_crawler(crawler)
elif hasattr(mwcls, 'from_settings'):
mw = mwcls.from_settings(settings)
else:
mw = mwcls()
I admit, I do not know if this is also the place where pipelines get created (I guess not, but there is no pipelines.py), but the implementation seems very reasonable.
So, I'd just either:
reimplement the whole method as from_crawler and only use that one
add method from_crawler and use both
The new method could look like follows (to duplicate as little code as possible):
#classmethod
def from_crawler(cls, crawler):
obj = cls.from_settings(crawler.settings)
obj.do_something_on_me_with_crawler(crawler)
return obj
Of course this depends a bit on what you need.