django-import-export how to merge/append instead of update for specific fields - django-import-export

I was able to get access to the new row data and existing instance by overriding import_obj.
def import_obj(self, instance, row, dry_run):
super(RelationshipResource, self).import_obj(instance, row, dry_run)
for field in self.get_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
tags = []
for tag in instance.tagtag.all():
tags.append(tag.name)
tags.extend(row['tagtag'].split(',')) # concat existing and new tagtag list
row['tagtag'] = ', '.join(tags) #set as new import value
# continue to save_m2m
continue
self.import_field(field, instance, row)
However, some where else in the import workflow it compares the values. Since the new concat value contains the original value the field is not updated. Import thinks there is no change.
How can i save the instance with the full concat values?

Related

Use an Ironpython script to filter and pass filter selections between tables

I have two tables in the analysis. I am using the script below to be able to filter table A and pass those filter selections to the matching filter in table B. Table A and B are visualized in a bar chart. I am triggering the code when the value of a document property changes, following instructions here.
I am running into two problems.
1) After the script runs, clicking Reset All Filters results in only table A being displayed in the visualization. Clicking Reset All Filters again fixes the issue.
2)When I add a second filter (commented out in the code below), making a selection in the Type_A or or Type_B filter wipes out the type B data from the visualization. I think the problem is in how IncludeAllValues is being handled, but I don't know how to fix it. Any help will be appreciated.
from Spotfire.Dxp.Application.Filters import *
from Spotfire.Dxp.Application.Visuals import VisualContent
from System import Guid
#Get the active page and filterPanel
page = Application.Document.ActivePageReference
filterPanel = page.FilterPanel
theFilterA = filterPanel.TableGroups[0].GetFilter("Type_A")
lbFilterA = theFilterA.FilterReference.As[ListBoxFilter]()
theFilter2A = filterPanel.TableGroups[1].GetFilter("Type_A")
lb2FilterA = theFilter2A.FilterReference.As[ListBoxFilter]()
lb2FilterA.IncludeAllValues = False
lb2FilterA.SetSelection(lbFilterA.SelectedValues)
#########################Type_B###########################
# theFilterB = filterPanel.TableGroups[0].GetFilter("Type_B")
# lbFilterB = theFilterB.FilterReference.As[ListBoxFilter]()
# theFilter2B = filterPanel.TableGroups[1].GetFilter("Type_B")
# lb2FilterB = theFilter2B.FilterReference.As[ListBoxFilter]()
# lb2FilterB.IncludeAllValues = False
# lb2FilterB.SetSelection(lbFilterB.SelectedValues)

Django rest framework mongoengine update new field with default value

I'm using Django rest framework mongoengine after created few documents, if i want add a new field with default value. Is there any way to do that orelse i need to update with few custom function.
Note: I want to fetch the data with filter having a new field name. That time the field is not there. So i'm getting empty.
From what I understand, you are modifying a MongoEngine model (adding a field with a default value) after documents were inserted. And you are having issue when filtering your collection on that new field.
Basically you have the following confusing situation:
from mongoengine import *
conn = connect()
conn.test.test_person.insert({'age': 5}) # Simulate an old object
class TestPerson(Document):
name = StringField(default='John') # the new field
age = IntField()
person = TestPerson.objects().first()
assert person.name == "John"
assert Test.objects(name='John').count() == 0
In fact, MongoEngine dynamically applies the default value when the field of the underlying pymongo document is empty but it doesn't account for that when filtering.
The only reliable way to guarantee that filtering will work is to migrate your existing documents.
If its only adding a field with a default value, you could do this with MongoEngine: TestPerson.objects().update(name='John')
If you did more important/complicated changes to your document structure, then the best option is to get down to pymongo.
coll = TestPerson._get_collection()
coll.update({}, {'$set': {'name': 'John'}})

Cannot Insert header using the before_import override function in django-import-export

I'm using django-import-export to upload csv files through django admin. I have the ability to override the before_import function to add functionality before the import. I have a csv file with no headers, and the actual data starts on line one. I need to add a header, or insert a row before my csv file is uploaded, so that it can be read properly.
class UpdateResource(resources.ModelResource):
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
dataset.header = ['sku', 'quantity']
class Meta:
model = Upload
import_id_fields = ('sku',)
This code changes the value of the first row of my csv file to sku,quantity, but I need to insert one above that value, not replace it. Alternatively, if there is an option to ignore headers and just map the values to my model from left to right or something, that would be great too.
My fix was to store the first row as a variable, create the desired header and append the first row to end of file.
class UpdateResource(resources.ModelResource):
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
first_row = dataset.header
dataset.header = ['sku', 'quantity']
dataset.append(first_row)

Odoo 10 - Duplicate supplier info for a given product_template

I have:
a) given product_template_id (i.e. id 100) and
b) a duplicated product_template_id (i.e. id 200) created using copy() method
copy() method copies only product.template model, so suppliers for that specific product are not copied.
I would like to duplicate all suppliers for that model, but now I am wondering which is the right way to do it in Odoo.
If I understood the model properly suppliers prices for a given product are stored in product_supplierinfo table, where each record that points to a given product_tmpl_id specifices a supplier price/qty for a given product_template.
Which would be the way in Odoo to search for all records that point to a given product_tmpl_id (i.e. 100), duplicate them changing product_tmpl_id to the new one (i.e. 200)?
Excerpt from the ORM Documentation:
copy (bool) -- whether the field value should be copied when the record is duplicated (default: True for normal fields, False for One2many and computed fields, including property fields and related fields)
The field you're referring to is seller_ids, whose field definition is below:
seller_ids = fields.One2many('product.supplierinfo', 'product_tmpl_id', 'Vendors')
The copy attribute is not explicitly defined, so it is False by default (as explained in the documentation above). If you want this field to copy along with the other values during the standard product "Duplicate" (copy method), you can do this:
class ProductTemplate(models.Model):
_inherit = 'product.template'
# This only changes the copy attribute of the existing seller_ids field.
# All other attributes (string, comodel_name, etc.) remain as they are defined in core.
seller_ids = fields.One2many(copy=True)
Alternatively
If you want to only have the field copied sometimes, you can extend the copy method to look for a specific context value and only copy based on that.
# This may take some tweaking, but here's the general idea
#api.multi
def copy(self, vals):
new_product = super(YourClass, self).copy(vals)
if vals.get('copy_sellers'):
new_product.seller_ids = self.seller_ids.copy({'product_id': new_product.id})
return new_product
# Whatever you have calling the copy method will need to include copy_sellers in vals
vals.update({'copy_sellers': True})
product.copy(vals)

Removing attributes from an activerecord got via .includes

I am having a really weird problem while attempting to do a very simple thing. I am doing an .includes on a model to get a row of data from the database. On the return object I need to remove certain attributes conditionally. And the final aim is to reinsert this row as a new record based on the changes I make on the attributes using my conditions.
def myUpdate
dbObj = Obj.includes(:name,
:addr1,
:addr2,
:state,
:description).find(params[:id])
#dbObjective.attributes().except('description')
#dbObjective.description = nil
#dbObjective.attributes().delete('description')
# After setting more attributes, persist this object
end
I tried all possibilities that I could think of, but the attribute is just not getting removed. What am I missing? I am on Ruby on Rails 4.2.
includes is used to include associated tables in your query for join queries and eager loading, not for table attributes. You do not need to do anything special to access an object's attributes.
attributes returns a Hash instance containing the record's attributes as key-value pairs, and operating on it will change only the Hash instance itself, not the record.
There are several ways to update attributes. One of the easiest ways is using the built in setter methods given to you by ActiveRecord. If you really want to change attributes using the Hash API you can store the attributes hash in a variable, manipulate the hash, and pass it as an argument to update, which accepts an attributes hash as it's argument.
Using setter methods
def myUpdate
dbObj = Obj.find(params[:id])
dbObj.description = 'new_description'
dbObj.name = 'new_name
dbObj.save
end
Using update
def myUpdate
dbObj = Obj.find(params[:id])
attributes = dbObj.attributes # This is how you would update the object by manipulating the attributes hash
attributes.delete(:description) # this will NOT end up changing the attribute in the DB
attributes[:name] = nil # this will successfully set name to NULL in the DB
dbObj.update(attributes) # pass the manipulated hash to the `update` method to persist the changes
end
deleteing fields from the hash will not have an effect on the persisted object. update only performs an insert on fields present in the hash that have changed.

Resources