I am wanting to create a method that will export a subset of product.product records to a CSV. My end goal is to get a csv to drop somewhere with those filtered product.product records. Then I'm going to use a scheduled action with the product.product object and my custom method to export this on a daily basis.
Any suggestions would be great. I feel like I just need to iterate over the records in the product.product model, and then pass each one to csv.writer. I'm a little new to python and not 100% on going over the individual members of that object.
Edit:
The Help Docs (Which are much better with 8.0) just cleared up for me that:
Methods defined on a model are executed on a recordset, and their self is a recordset:
class AModel(models.Model): _name = 'a.model' def a_method(self): # self can be anywhere between 0 records and all records in the # database self.do_operation()
So, I think I'm looking for something like this:
import csv
from openerp.osv import fields, osv
class product_product(osv.Model):
_inherit = 'product.product'
def _export_products_to_csv(self, fields, rows):
fp = StringIO()
writer = csv.writer(fp, quoting=csv.QUOTE_ALL)
writer.writerow([name.encode('utf-8') for name in fields])
for row in rows:
writer.writerow(row)
fp.close()
Per my comment below (which trashed the formatting for the code), here is the code I find in addons\web\controllers\main.py which appears to be the controller for creating the csv file. It looks like open just uses the csv writer from python's built in library:
class CSVExport(ExportFormat, http.Controller):
@http.route('/web/export/csv', type='http', auth="user")
@serialize_exception
def index(self, data, token):
return self.base(data, token)@property
def content_type(self):
return 'text/csv;charset=utf8'def filename(self, base):
return base + '.csv'def from_data(self, fields, rows):
fp = StringIO()
writer = csv.writer(fp, quoting=csv.QUOTE_ALL)writer.writerow([name.encode('utf-8') for name in fields])
for data in rows:
row = []
for d in data:
if isinstance(d, basestring):
d = d.replace('\n',' ').replace('\t',' ')
try:
d = d.encode('utf-8')
except UnicodeError:
pass
if d is False: d = None
row.append(d)
writer.writerow(row)fp.seek(0)
data = fp.read()
fp.close()
return data
I'll drop my solution on GitHub once I get this figured out.
Ugh, I can't comment on your answer Ludo because of Karma... I found that method, I think in the web module. I'll drop it into this question once I have a chance. I considered doing that but since python's csv is so readily available, I thought it would be easier as long as I could pass it the right data from product.product.