How to store multiple values in One2many field through odoo website - python-3.x

I have made a Bulk Inquiry form in odoo website. In which the fields category, qty, brand are to be repeated on clicking Click To Select More Products
Webpage Image:
The problem which I am facing is, values of first row are stored in database but fails to store the values for the next product/category and I have to store it in One2many field
Here is my code (controllers.py):
#http.route(['/website_form/'], auth='public', website=True,methods=['POST', 'GET'], csrf=False, type="http")
def bulkorder(self, **kwargs):
if kwargs:
contact_name = kwargs.get('contact_name')
phone = kwargs.get('phone')
email_from = kwargs.get('email_from')
partner_name = kwargs.get('partner_name')
designation = kwargs.get('designation')
gst_no = kwargs.get('gst_no')
name = kwargs.get('name')
description = kwargs.get('description')
category = kwargs.get('category')
quantity = kwargs.get('quantity')
brand = kwargs.get('brand')
select_type = kwargs.get('select_type')
lines = [(0,0,{'category':category,
'quantity':quantity,
'brand':brand})]
user_data = {
'contact_name': contact_name,
'phone': phone,
'email_from': email_from,
'partner_name': partner_name,
'designation': designation,
'gst_no': gst_no,
'name':name,
'description': description,
'select_type': select_type,
'bulk_order_line':lines,
'select_type':select_type,
}
store = http.request.env['bulk.order']
store.create(user_data)
store.bulk_order_line.write({})
return http.local_redirect('/contactus-thank-you')
models.py:
from odoo import models, fields, api,_
from odoo.exceptions import UserError
from odoo import SUPERUSER_ID
class EIndustry_bulkorder(models.Model):
_name = 'bulk.order'
contact_name=fields.Char(string="Full Name")
phone=fields.Char(string="Phone Number", limit=10)
email_from=fields.Char(string="Email")
partner_name=fields.Char(string="Company Name")
designation=fields.Char(string="Designation")
gst_no=fields.Char(string="GST Number")
name=fields.Char(string="Subject")
description=fields.Char(string="Your Question")
category=fields.Char(string="Product/Category")
quantity=fields.Char(string="quantity")
brand=fields.Char(string="Brand/Make")
lead=fields.Char(string="Lead")
select_type=fields.Many2one('bulk.retailer' , string="Profession",
required=True , store = True)
bulk_order_line = fields.One2many('bulk.bulk_order_lines','bulk_order_line_id',
string='Bulk Order Lines')
class retailerType(models.Model):
_name='bulk.retailer'
name = fields.Char(string="Retailer Name")
class BulkOrderLine(models.Model):
_name = 'bulk.bulk_order_lines'
bulk_order_line_id=fields.Many2one('bulk.order','bulk_order_line',
ondelete='cascade', index=True, copy=False)
category=fields.Char(string="Product/Category")
quantity=fields.Char(string="Quantity")
brand=fields.Char(string="Brand")

Related

Save all data in database with one query in Django

I'm a new Django programmer. I write a API call with rest_framework in Django. when call this API, my program connect to KUCOIN and get list of all cryptocurrency. I want save symbol and name this cryptocurrencies in database. For save data to database, I use 'for loop' and in every for loop iteration, I query to database and save data. my code :
for currencie in currencies:
name = currencie['name']
symbol = currencie['symbol']
active = (False, True)[symbol.endswith('USDT')]
oms = 'kucoin'
try:
obj = Instrument.objects.get(symbol=symbol, oms=oms)
setattr(obj, 'name', name)
setattr(obj, 'active', active)
obj.save()
except Instrument.DoesNotExist:
obj = Instrument(name=name, symbol=symbol,
active=active, oms=oms)
obj.save()
query to database in every for loop iteration have problem ,How can I solve this problem?
Exist any way in Django to save data in database in with one query.
All my code:
class getKucoinInstrument(APIView):
def post(self, request):
try:
person = Client.objects.filter(data_provider=True).first()
person_data = ClientSerializer(person, many=False).data
api_key = person_data['api_key']
api_secret = person_data['secret_key']
api_passphrase = person_data['api_passphrase']
client = kucoin_client(api_key, api_secret, api_passphrase)
currencies = client.get_symbols()
for currencie in currencies:
name = currencie['name']
symbol = currencie['symbol']
active = (False, True)[symbol.endswith('USDT')]
oms = 'kucoin'
try:
obj = Instrument.objects.get(symbol=symbol, oms=oms)
setattr(obj, 'name', name)
setattr(obj, 'active', active)
obj.save()
except Instrument.DoesNotExist:
obj = Instrument(name=name, symbol=symbol,
active=active, oms=oms)
obj.save()
return Response({'response': 'Instruments get from kucoin'}, status=status.HTTP_200_OK)
except Exception as e:
print(e)
return Response({'response': 'Internal server error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Thank you for you help.
Yes! Take a look at bulk_create() documentation. https://docs.djangoproject.com/en/4.0/ref/models/querysets/#bulk-create
If you have a db that supports ignore_conflicts parameter (all do, except Oracle), you can do this:
new_currencies = []
for currencie in currencies:
name = currencie['name']
symbol = currencie['symbol']
active = (False, True)[symbol.endswith('USDT')]
oms = 'kucoin'
new_currencies.append(Instrument(name=name, symbol=symbol,
active=active, oms=oms))
Instrument.objects.bulk_create(new_currencies, ignore_conflicts=True)
1-liner:
Instrument.objects.bulk_create(
[
Instrument(
name=currencie['name'], symbol=currencie['symbol'],
active=currencie['symbol'].endswith('USDT'), oms='kucoin'
)
for currencie in currencies
],
ignore_conflicts=True
)

write attribute_line_ids in product.tempate in odoo 12

i am getting fields data from xls file and creating product
everything work fine except one2many field of variant in product.template
how can i achieve this.
here is my code.
main_product = self.env["product.template"].create(product_data)
attribute_ids = self.env["product.attribute"].search([])
attrib_id_set = set(ids.name for ids in attribute_ids)
product_attrib_ids = sheet.cell(suits, 13).value.split(",")
attrib_id_list = []; exist_attribute_list = []
for name in product_attrib_ids:
if name not in attrib_id_set:
attrib_id = self.env["product.attribute"].create({'name':name})
attrib_id_list.append(attrib_id)
else:
exist_attribute = self.env["product.attribute"].search([('name','=',name)])
exist_attribute_list.append(exist_attribute)
union_list = list(set(attrib_id_list).union(exist_attribute_list))
exist_attribute_values = self.env["product.attribute.value"].search([])
exist_attrib_val_list = [attrib_name.name for attrib_name in exist_attribute_values]
product_attrib_id_values = sheet.cell(suits, 14).value.split(",")
for value in product_attrib_id_values:
if value not in exist_attrib_val_list:
for ids in union_list:
attrib_value_id = self.env["product.attribute.value"].create({
'attribute_id':ids.id,
'name':value
})
main_product.write({
'attribute_line_ids':[(0,0,{
'attribute_id':ids.id, 'value_ids':(4,attrib_value_id.id)
})]
})
product_data is my dictionary for fields like name,sale_ok,type,catag_id etc.
this works, product is created, attribute_id and attribute values even works
but i can not write one2many of variant in product.template.
--EDIT--
values_lst=[]
for value in product_attrib_id_values:
if value not in exist_attrib_val_list:
for ids in union_list:
attrib_value_id = self.env["product.attribute.value"].create({
'attribute_id':ids.id,
'name':value
})
else:
for ids in exist_attribute_values:
if value == ids.name:
attrib_value_id =self.env["product.attribute.value"].browse(ids.id)
if attrib_value_id not in values_lst:
values_lst.append(attrib_value_id)

Many2many field tableundefined odoo, can't get multiple many2many fields

I have multiple Many2many fields but I'm getting the following error:
relation stream doesn't exist,undefined-table
I cannot find where this error is occurring. Can someone help me fix this error?
class College(models.Model):
_name = 'module5_college'
_description = 'College Info'
_rec_name = 'clg'
clg = fields.Char("College Name")
uni = fields.Char("Affiliated to")
cou = fields.Many2many('module5_stream',string="Stream")
class Stream(models.Model):
_name = 'module5_stream'
_description = 'Stream info'
_rec_name = 'cou'
cou = fields.Selection([
('BTECH', 'BTECH'),
('MTECH', 'MTECH'),
('MCA', 'MCA')],"Stream")
cou_mode = fields.Selection([
('Regular','Regular'),
('Lateral','Lateral'),
('Distance','Distance')],"Course Mode")
sem_no = fields.Integer("No of semesters")
# full_score = fields.Integer(compute='score_calc',string="Score")
sem = fields.Many2many('module5_sem',"Semesters")
class Semester(models.Model):
_name = 'module5_sem'
_rec_name = 'id'
sem_no = fields.Char("Semester No")
sub = fields.Many2many('module5_subject',"Subjects")
You have to follow this example because this is the way to create many2many field:
employees_ids = fields.many2many('Employees.Employees', 'tasks_employees_rel', 'task_id', 'employee_id', 'Employees assigned to task')
To give you a better example.
A employee can be assigned to many tasks
A task can be assigned to many employees
So you have a many2many relation, so that means that you have to create a new table containing both keys.

i have added a field in existing module "hr.payslip" from my module.How to show the data of that field

an existing module is present i.e hr.payslip,In that module i have added a field from my module . now i want to display the value of that field in hr.payslip module.
models/emailpayslip.py
#api.multi #Decorate a record-style method where 'self' is a recordset. The method typically defines an operation on records.
def send_email(self):
ir_model_data = self.env['ir.model.data']
payslip_obj = self.env['hr.payslip']
ids = self.env.context.get('active_ids', [])
ctx = dict()
employee_name = ''
for id_vals in ids:
payslip_browse = payslip_obj.browse(id_vals)
global email
email = payslip_browse.employee_id.work_email
store_email.sql_example(self,email)#calling method of store_email model
if payslip_browse.employee_id.work_email:
template_id = ir_model_data.get_object_reference('Payslip', 'email_template_payslip')[1]
ctx.update({
'default_model': 'hr.payslip',
'default_res_id': payslip_browse.id,
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'email_to': payslip_browse.employee_id.work_email,
})
mail_id = self.env['mail.template'].browse(template_id).with_context(ctx).send_mail(payslip_browse.id, True)
This model is used to create a new table in database and store email to which the payslip is send and date of payslip send
class store_email(models.Model):
_name = "store.email"
sendemail = fields.Char(
string='Send Email',
default=lambda self: self._get_default_name(),
)
no_of_times = fields.Integer(string='No of Times')
date_of_email_send = fields.Date(
string="Date of Email",
default=lambda self: fields.datetime.now())
#api.model
def _get_default_name(self):
return "test"
#api.multi
def sql_example(self,temp):
dob = datetime.today()
self.env.cr.execute("SELECT * FROM store_email WHERE sendemail = %s",(temp,))
res = self.env.cr.fetchall()
if res == []:
count = 1
self.env.cr.execute("INSERT INTO store_email (sendemail,no_of_times,date_of_email_send) VALUES (%s,%s,%s)",(temp,count,dob))
self.env.cr.commit()
else:
for x in res:
count = x[7] + 1
self.env.cr.execute("UPDATE store_email SET date_of_email_send=%s,no_of_times=%s WHERE sendemail=%s",(dob,count,temp))
self.env.cr.commit()
Model to add a field in hr.payslip ,Which show last payslip send date
class Add_Field(models.Model):
_inherit = "hr.payslip"
last_payslip_send = fields.Date(string='Last Payslip Send')
#api.multi
def last_send_payslip(self):
self.env.cr.execute("SELECT * FROM store_email WHERE sendemail=%s",(email,))
res = self.env.cr.fetchall()
my addfile.xml
add_newfield
screenshort of the page where i have added the field
this page cntain the screenshort
You can use compute or default function to load value in to field or you can also pass value while creating record
default function example:
name = fields.Char(
string='Name',
default=lambda self: self._get_default_name(),
)
#api.model
def _get_default_name(self):
return "test"
Refer this link for computed fields

How can i change a boolean value in model A, when a new instance of model B (have many2one field to model A) is created in ODOO 12?

I have two odoo 12 models,(biblio.location and biblio.book),
-the model "biblio.book" contains a boolean "disponibile" set to true by defaul.
-the model "biblio.location" have a many2one field references to model "biblio.book".
i want the value of the boolean "disponible" in biblio.book to be changed automatically (change also in database) when a new instance of biblio.location is created, in other way when we rent(location) a book we must change disponibility in model book to FALSE.
i tried "computed field, #api.onchange and #api.depends" and nothing works for me, please help me in this issue and i want to know de difference between those three mehods.thank you
class book(models.Model):
_name = 'biblio.book'
_description = 'All books'
name=fields.Char()
annee_edition = fields.Date(string="année d'édition")
ISBN = fields.Integer(required=True)
editor = fields.Char(required=True)
auteur = fields.Many2many('biblio.author',string='auteur_livre',required=True)
disponible=fields.Boolean(default=True,required=True,related='biblio.location.disponible',store=True )
class location(models.Model):
_name = 'biblio.location'
_description = 'All librarians'
name=fields.Char()
livre = fields.Many2one('biblio.book',string='livre',required=True,domain =[('disponible','=',True)])
client = fields.Many2one('biblio.customer',string="client",required=True)
date_location =fields.Datetime(required=True)
date_retour_prevu=fields.Datetime(required=True,string="Date retour prévu")
date_retour_reelle=fields.Datetime(required=True,string="Date retour réelle")
disponible = fields.Boolean(default=False)
File "C:\Users\PycharmProjects\Odoo12\odoo\odoo\fields.py", line 484, in setup_full
self._setup_related_full(model)
File "C:\User\PycharmProjects\Odoo12\odoo\odoo\fields.py", line 527, in _setup_related_full field = target._fields[name]
KeyError: 'biblio' - - -
OK, for this to work the way you want it you need to set up a foreign key in your biblio.book model.
book_location = fields.Many2one('biblio.location', string='Book Location')
Then you can do your computed field
disponible = field.Boolean(compute='_disponible', string='Available for Loan', default=False)
#api.model
def _disponible(self):
for book in self:
book.disponible = True if book.book_location else False
You don't want to set this as storable as you want it to check every time that the field is called. If you set it to storable it will only compute when the record is created.

Resources