write attribute_line_ids in product.tempate in odoo 12 - python-3.x

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)

Related

how to insert multiple rows into sqllite3 database

I am trying to select rows and fetch them from the DB table and then insert them into a list so I can insert all of the rows at once into the database, but I got an error.
def paid_or_returned_buyingchecks(self):
date = datetime.now()
now = date.strftime('%Y-%m-%d')
self.tenlistchecks=[]
self.con = sqlite3.connect('car dealership.db')
self.cursorObj = self.con.cursor()
self.dashboard_buying_checks_dates = self.cursorObj.execute("select id, paymentdate , paymentvalue, car ,sellername from cars_buying_checks where nexttendays=?",(now,))
self.dashboard_buying_checks_dates_output = self.cursorObj.fetchall()
self.tenlistchecks.append(self.dashboard_buying_checks_dates_output)
print(self.tenlistchecks)
self.dashboard_buying_checks_dates = self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",[self.tenlistchecks])
self.con.commit()
but I got an error :
[[(120, '21-08-2022', '1112', 'Alfa Romeo', 'james'), (122, '21-08-2022', '465', 'Buick', 'daniel '), (123, '21-08-2022', '789', 'Buick', 'daniel ')]]
self.dashboard_buying_checks_dates = self.cursorObj.executemany(
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 5, and there are 1 supplied.
self.cursorObj.fetchall() returns a list of tuples, which is what you need to feed to executemany, so
self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",self.tenlistchecks)
not
self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",[self.tenlistchecks])

How to add multiple fields' reference to "unique_together" error message

I have a model with multiple fields being checked for uniqueness:
class AudQuestionList(BaseTimeStampModel):
aud_ques_list_id = models.AutoField(primary_key=True,...
aud_ques_list_num = models.CharField(max_length=26,...
aud_ques_list_doc_type = models.ForeignKey(DocType,...
short_text = models.CharField(max_length=55,...
aud_scope_standards = models.ForeignKey(ScopeStandard, ...
aud_freqency = models.ForeignKey(AuditFrequency, ...
aud_process = models.ForeignKey(AuditProcesses, ...
unique_together = [['aud_scope_standards', 'aud_freqency', 'aud_process',],]
My model form is as described below:
class CreateAudQuestionListForm(forms.ModelForm):
class Meta:
model = AudQuestionList
fields = ('aud_ques_list_doc_type', 'aud_scope_standards', 'aud_freqency', 'aud_process', 'short_text', ...
def validate_unique(self):
try:
self.instance.validate_unique()
except ValidationError:
self._update_errors({'aud_scope_standards': _('Record exists for the combination of key values.')})
The scenario works perfectly well, only that the field names (labels) itself are missing from the message.
Is there a way to add the field names to the message above, say something like:
Record exists for the combination of key fields + %(field_labels)s.

Django model.save() not updating model instance

I am trying to update a handful of fields if the record has been marked as deleted. When I debug, I can see that the values are being assigned in the view, but not being updated in the DB. I'm not sure what I'm missing.
views.py
contact_formset = ContactFormSet(request.POST, prefix='contact')
for contact in contact_formset.deleted_forms:
contact = contact.cleaned_data
print(contact)
instance = contact['id_cnt']
contact_id = instance.id_cnt
contact_object = get_object_or_404(AppContactCnt, id_cnt=contact_id)
contact_object.deleted_cnt = True
contact_object.date_deleted_cnt = '2020-11-23'
contact_object.deleted_by_cnt = 'adeacon'
contact_object.save()
Included the delete code with the edit code. Seemed to do the trick:
if '_edit_contact_formset' in request.POST:
contact_formset = ContactFormSet(request.POST, prefix='contact')
for contact_form in contact_formset:
if contact_form.is_valid() and contact_form.has_changed():
contact_data = contact_form.cleaned_data
# print(contact_data)
customer_obj = get_object_or_404(AppCustomerCst, id_cst=id)
contact_form.instance.idcst_cnt = customer_obj
contact_form.instance.idtrp_cnt = '-1'
if contact_data['DELETE'] is True:
print('delete me')
contact_form.instance.deleted_cnt = True
contact_form.instance.date_deleted_cnt = '2020-11-23'
contact_form.instance.deleted_by_cnt = 'adeacon'
messages.info(request, 'Contact deleted successfully')
contact_form.save()
formset = ContactFormSet(
queryset=AppContactCnt.objects.filter(idcst_cnt=id).exclude(deleted_cnt=True).select_related('idctp_cnt'),
prefix='contact')
if contact_data['DELETE'] is not True:
messages.info(request, 'Contacts updated successfully!')

Python list add variables in rows

im trying to add variables to a list that i created. Got a result from a session.execute.
i´ve done this:
def machine_id(session, machine_serial):
stmt_raw = '''
SELECT
id
FROM
machine
WHERE
machine.serial = :machine_serial_arg
'''
utc_now = datetime.datetime.utcnow()
utc_now_iso = pytz.utc.localize(utc_now).isoformat()
utc_start = datetime.datetime.utcnow() - datetime.timedelta(days = 30)
utc_start_iso = pytz.utc.localize(utc_start).isoformat()
stmt_args = {
'machine_serial_arg': machine_serial,
}
stmt = text(stmt_raw).columns(
#ts_insert = ISODateTime
)
result = session.execute(stmt, stmt_args)
ts = utc_now_iso
ts_start = utc_start_iso
ID = []
for row in result:
ID.append({
'id': row[0],
'ts': ts,
'ts_start': ts_start,
})
return ID
In trying to get the result over api like this:
def form_response(response, session):
result_machine_id = machine_id(session, machine_serial)
if not result_machine_id:
response['Error'] = 'Seriennummer nicht vorhanden/gefunden'
return
response['id_timerange'] = result_machine_id
Output looks fine.
{
"id_timerange": [
{
"id": 1,
"ts": "2020-08-13T08:32:25.835055+00:00",
"ts_start": "2020-07-14T08:32:25.835089+00:00"
}
]
}
Now i only want the id from it as a parameter for another function. Problem is i think its not a list. I cant select the first element. result_machine_id[0] result is like the posted Output. I think in my first function i only add ts & ts_start to the first row? Is it possible to add emtpy rows and then add 'ts':ts as value?
Help would be nice
If I have understood your question correctly ...
Your output looks like dict. so access its id_timerange key which gives you a list. Access the first element which gives you another dict. On this dict you have an id key:
result_machine_id["id_timerange"][0]["id"]

Melting a List in column to multiple rows in dataframe

What I am trying to do is, I have a list of star_cast and list of a genre for a single movie entity. I want to melt this list down as a repeating entity in data frame so that I can store it in a database system.
director_name = ['chris','guy','bryan']
genre = [['mystery','thriller'],['comedy','crime'],['action','adventure','sci -fi']]
gross_vlaue = [2544,236544,265888]
imdb_ratings = [8.5,5.4,3.2]
metascores = [80.0,55.0,64.0]
movie_names = ['memento','snatch','x-men']
runtime = [113.0,102.0,104.0]
star_cast = [['abc','ced','gef'],['aaa','abc'],['act','cst','gst','hhs']]
votes = [200,2150,2350]
sample_data = pd.DataFrame({"movie_names":movie_names,
"imdb_ratings":imdb_ratings,
"metscores":metascores,
"votes":votes,
"runtime":runtime,
"genre":genre,
"director_name": director_name,
"star_cast": star_cast,
"gross_value":gross_vlaue
})
The above will generate a Data Frame sample I have.
director_name = ['chris','chris','chris','chris','chris','chris','guy','guy','guy','guy','bryan','bryan','bryan','bryan','bryan','bryan','bryan','bryan','bryan','bryan','bryan','bryan']
genre = ['mystery','thriller','mystery','thriller','mystery','thriller','comedy','crime','comedy','crime','action','adventure','sci -fi','action','adventure','sci -fi','action','adventure','sci -fi','action','adventure','sci -fi']
gross_vlaue = [2544,2544,2544,2544,2544,2544,236544,236544,236544,236544,265888,265888,265888,265888,265888,265888,265888,265888,265888,265888,265888,265888]
imdb_ratings = [8.5,8.5,8.5,8.5,8.5,8.5,5.4,5.4,5.4,5.4,3.2,3.2,3.2,3.2,3.2,3.2,3.2,3.2,3.2,3.2,3.2,3.2]
metascores = [80.0,80.0,80.0,80.0,80.0,80.0,55.0,55.0,55.0,55.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0,64.0]
movie_names = ['memento','memento','memento','memento','memento','memento','snatch','snatch','snatch','snatch','x-men','x-men','x-men','x-men','x-men','x-men','x-men','x-men','x-men','x-men','x-men','x-men']
runtime = [113.0,113.0,113.0,113.0,113.0,113.0,102.0,102.0,102.0,102.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0,104.0]
star_cast = ['abc','ced','gef','abc','ced','gef','aaa','abc','aaa','abc','act','cst','gst','hhs','act','cst','gst','hhs','act','cst','gst','hhs']
votes = [200,200,200,200,200,200,2150,2150,2150,2150,2350,2350,2350,2350,2350,2350,2350,2350,2350,2350,2350,2350]
sample_result = pd.DataFrame({"movie_names":movie_names,
"imdb_ratings":imdb_ratings,
"metscores":metascores,
"votes":votes,
"runtime":runtime,
"genre":genre,
"director_name": director_name,
"star_cast": star_cast,
"gross_value":gross_vlaue
})
This will generate the format I want to conver my data into.
I tried using melt() but no luck there. Please help, as to how it can be achieved in an effective way. My dataset is fairly large, using for loops will be very slow. Is there any other way around solving this?

Resources