Search code examples
pythonodoo

How to iterate over values of a recordset?


I am working on generating a csv report. I need to get the field names for the first row of the csv file and the value of the field for each record.

Since the model from which I need to generate the report is being inherited by other models and new fields can be created in the child models. I need to be able to dynamically get the field names.

In my class I'm using the following, which is what has worked best so far:

class MyClass(models.Model):
_inherit = 'custom.model'

    def csv_export(self):
        headings = self.fields_get()
        header = list(headings.keys())
        print(header)
        # header returns the list below
        # ['field1', 'field2', ...]

Now, in order to get the recordset, I am performing a search with some criteria to narrow down the records to the data that I need. It looks as follows:

records = self.env['custom.model'].search([('country', '=', 'US')], limit=n)

Next, I iterate through the "records" to extract the value of each field in the record. The loop looks like this:

for rec_val in records:
    print(rec_val.state) 
    # 'state' being one of the fields in the model
    # ['Florida', 'Georgia', ...]

Good so far. But since "rec_val.state" is hard-coded and the field name could have changed or new fields could have been added to the child models. I need to access the values of "records" while looping, using the "keys" I extracted for the field names, that are stored in the "header" list.

The way I attempted to do that is as follows:

for index, rec_val in enumerate(records):
    print(rec_val[header[index]]) # this throws an exception
    print(rec_val.header[index]) # this also throws an exception

So, I can access the values when I use "rec_val.state", but I have not found the proper way to access them otherwise.

The reason why I'm trying to use the field name as key to access the value, is because I also need to exclude (while looping) some fields that are not needed. So it can't be hard-coded either.

When I use "search_read" as my method on the model, like so:

records = self.env['custom.model'].search_read([('country', '=', 'US')], limit=n)

I get a more manageable recordset, more a plain list. But I still can't use the "header[index]" to match the value to the key.

Hopefully the above makes sense and one of you can point me in the right direction.

Thanks


Solution

  • In your example, you're trying to use the index of records to access values in headers.

    I believe the below is what you intended to do?

    for rec_val in records:
        for header in headers:
            value = getattr(rec_val, header)
            print(value)