I think the best approach would be to create a wizard for this. You
generate a wizard by creating a class that inherits from TransientModel.
An instance of it will not stay in the database forever, as it is
intended for processes (for example your import).
I would
suggest, that you create a completely new view with a file upload dialog
and an import button. The xml for that looks something like this
(you'll have to adapt the names):
<odoo>
<data>
<record id="your_wizard_form" model="ir.ui.view">
<field name="name">your.wizard.form</field>
<field name="model">your_wizard</field>
<field name="arch" type="xml">
<form string="Import a csv file">
<group name="main">
<field name="csv_file" />
</group>
<footer>
<button name="import_csv" type="object"
string="Import" class="oe_highlight"/>
<button special="cancel" string="Cancel"/>
</footer>
</form>
</field>
</record>
<record id="your_wizard_action" model="ir.actions.act_window">
<field name="name">Import a csv file</field>
<field name="res_model"your_wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem id="your_wizard_menu"
parent="SOME_MENU_IN_PURCHASE"
action="your_wizard_action"
sequence="15" />
</data>
</odoo>
What this does is the following:
-
You create a new view your_wizard_form with a field csv_file (your file
upload), and two buttons: Import and Cancel. Cancel is handled by Odoo
by default, if you define it as special="cancel". The import button will
execute the python function import_csv of the model your_wizard.
-
The remaining stuff is basically additional code, to add your import
dialog as a menu item. You don't have to do it like this, there are
other ways too.
Now to the python code. Your wizard class should look like this:
class YourWizard(models.TransientModel):
_name = 'your_wizard'
# your file will be stored here:
csv_file = fields.Binary(string='CSV File', required=True)
@api.multi
def import_csv(self):
# this will get executed when you click the import button in your form
return {}
Here
fields.Binary tells Odoo, that this is a file upload. Your file will
get stored in base64 encoded form, so to use the csv reader, you'll have
to at first decode it from base64 and split it into lines for the csv
python module:
reader = csv.DictReader(base64.b64decode(self.csv_file).split('\n'))
Then
you'll have a DictReader that you can use to read the data from your
csv file and create new records directly in the database.
Note
that this will only work for csv files encoded with UTF-8. For files
with different encodings, you have to insert another step:
reader = csv.DictReader(base64.b64decode(self.csv_file).decode('file_encoding').encode('utf-8').split('\n'))
where
you replace file_encoding with the correct encoding (I have seen you
are using Linux, you can get the file encoding using the 'file'
command).
This is probably a lot to digest and it does not even
tell you how to write the data to the database. If you could specify
what you are trying to write, I might be able to help you further.
Database writes are usually quite simple, once you know which fields of
which models you want to write (that's the hard part).
EDIT: As noted in the comments, this code is copy-pasted from my own addon. I forgot to change some variable names (changed bom_file -> csv_file).
https://stackoverflow.com/questions/46783504/expand-groups-when-button-is-clicked
https://stackoverflow.com/questions/46783504/expand-groups-when-button-is-clicked