How to add multiple fields' reference to "unique_together" error message - python-3.x

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.

Related

django-import-export - Export one to many relationship with ForeignKeyWidget - returns an empty Field

I am trying to use the dajngo-import-export package to export data from two tables with a one to many relationship. I have a custom ForeignKeyWidget class that overrides the get_queryset method.
The problem is that the export returns an empty field - no errors, just an empty field. I also tried just using the ForeignKeyWidget without the custom class/get_queryset - but I get the same result.
Does anyone see what I'm doing wrong here?
#admin.py
from import_export import resources
from import_export.fields import Field
from import_export.widgets import ForeignKeyWidget
class SlateDocResource(resources.ModelResource):
actbreaks = Field(
column_name="actbreaks",
attribute="id",
widget=ActBreaksForeignKeyWidget(ActTimecodes, "slatedoc_id"),
)
class Meta:
model = SlateDoc
fields = [
"actbreaks",
]
class ActBreaksForeignKeyWidget(ForeignKeyWidget):
def get_queryset(self, value, row, *args, **kwargs):
qs = ActTimecodes.objects.filter(slatedoc_id=self.pk)
print(qs.values())
return qs
#models.py
class SlateDoc(models.Model):
#primary Model - fields not listed here.
class ActTimecodes(models.Model):
#Secondary model - every slatedoc can have multiple instances of ActTimecodes
slatedoc = models.ForeignKey(
SlateDoc,
on_delete=models.CASCADE,
related_name="acts"
)
act_number = models.IntegerField(verbose_name="Act", default=1)
tc_in = models.CharField(max_length=11, default="00:00:00:00")
tc_out = models.CharField(max_length=11, default="00:00:00:00")
dur = models.CharField(max_length=11, default="00:00:00:00")
objects = ActTimecodesQuerySet.as_manager()
class Meta:
ordering = ["act_number", "tc_in", "tc_out"]
#version info
"python_version": { "version": ==3.10" }
"django": { "version": "==4.1.1" },
"django-import-export": { "version": "==2.8.0"},
Here is the solution that I figured out.
The answer is very simple compared to what I was attempting to do - using the ForeignKey was totally unnecessary.
#admin.py
class SlateDocResource(resources.ModelResource):
actbreaks = Field(column_name="Act Breaks")
def dehydrate_actbreaks(self, slatedoc):
actbreaks = []
count = 1
for x in ActTimecodes.objects.filter(slatedoc_id=slatedoc.id):
tc_in = f"{count}_in"
tc_out = f"{count}_out"
duration = f"{count}_dur"
actbreak = {tc_in: x.tc_in, tc_out: x.tc_out, duration: x.dur}
actbreaks.append(actbreak)
count += 1
return actbreaks
the code above returns each actbreak as a dict in a list:
[{'tc_1_in': '01:00:00:00', 'tc_1_out': '01:13:34:00', 'act_1_dur': '00:13:34;00'}, {'tc_2_in': '01:13:36:00', 'tc_2_out': '01:19:03:00', 'act_2_dur': '00:05:26;28'}, {'tc_3_in': '01:19:05:00', 'tc_3_out': '01:26:13:00', 'act_3_dur': '00:07:08;02'}, {'tc_4_in': '01:26:15:00', 'tc_4_out': '01:31:16:00', 'act_4_dur': '00:05:01;02'}, {'tc_5_in': '01:31:18:00', 'tc_5_out': '01:37:39:00', 'act_5_dur': '00:06:21;00'}, {'tc_6_in': '01:37:41:00', 'tc_6_out': '01:44:10:00', 'act_6_dur': '00:06:29;00'}]

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)

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.

Python PonyORM One to one mapping

I am trying to create a one-to-one mapping using Pony ORM.
class ApplierIngress(ApplierObjectMapper.db.Entity):
correlation_id = orm.PrimaryKey(str)
ticket_number = orm.Required(str)
username = orm.Required(str)
status = orm.Required(str)
request_date = orm.Required(datetime)
class ApplierResult(ApplierObjectMapper.db.Entity):
correlation_id = orm.Required(ApplierIngress)
result = orm.Required(orm.LongStr)
request_date = orm.Required(datetime)
It throws error while generating the mapping
pony.orm.core.ERDiagramError: Reverse attribute for ApplierResult.correlation_id not found
I want correlation_id in ApplierResult table be the foreign key referencing to correlation_id in ApplierIngress table
Please let me know what am I doing wrong?
As error said you need to specify reverse attribute. Entities is not just Tables.
class ApplierIngress(ApplierObjectMapper.db.Entity):
correlation_id = orm.PrimaryKey(str)
ticket_number = orm.Required(str)
username = orm.Required(str)
status = orm.Required(str)
request_date = orm.Required(datetime)
result_id = orm.Optional('ApplierResult') # this attribute should be added
class ApplierResult(ApplierObjectMapper.db.Entity):
correlation_id = orm.Required(ApplierIngress)
result = orm.Required(orm.LongStr)
request_date = orm.Required(datetime)
Since this class is not yet declared you should use it as string or lambda
result_id = orm.Optional('ApplierResult')
result_id = orm.Optional(lambda: ApplierResult)
See here

select on sub query peewee

I am wondering if I can do select() on sub_query.
I am able to do join sub_query with any peewee.Model. But when I wrote a sub_query and I wanted to just group by with one of the column
e.g. sub_query.select(sub_query.c.column_1, fn.COUNT(sub_query.c.column2)alias('col2_count')).group_by(sub_query.c.column_1)
query was not nested and was giving SQL syntax error.
(Can't reveal the code)
(I have done alias() on sub_query)
Edit
Example:
class Product(Model):
id = PrimaryKeyField()
name = CharField()
created_date = DateField()
class Part(Model):
id = PrimaryKeyField()
product = ForeignKeyField(Product)
name = CharField()
class ProductError(Model):
id = PrimaryKeyField()
product = ForeignKeyField(Product)
note = CharField()
class PartError(Model):
id = PrimaryKeyField()
part = ForeignKeyField(Part)
error = ForeignKeyField(ErrorMaster)
Here Product can have general error and
parts can have specific error which are predefined in ErrorMaster
I just want to know count of product which have errors against total products date wise. (error is product error or error in any part)
So sub_query is something like
sub_q = Product.select(
Product.created_date,
Product.id.alias('product_id'),
fn.IF(# checks if product has error
ProductError.is_null(True), if no product error check part error
fn.IF(fn.COUNT(PartError.id) == 0, 0, 1), # checks if error count > 0 then there is error in part
1
).alias('is_error')
).join(Part, on=Product.id == Part.product)
.join(ProductError, JOIN_LEFT_OUTER, on=Product.id == ProductError.product)
.join(PartError, JOIN_LEFT_OUTER, on=PartError.part == Part.id)
.where(Product.created_date.between(from_date, to_date))
.group_by(Product.id).alias('some_alias')
# below does not work but I can do this in sql
query = sub_q.select(sub_q.c.created_date,
fn.COUNT(sub_q.c.product_id).alias('total_products'),
fn.SUM(sub_q.c.is_error).alias('product_with_errors'))
.group_by(sub_q.c.created_date)

Resources