1

Very simple question: can you make a custom attribute for a Field? I have a Customer model with a bunch of Fields. Charfields, ForeignKeys,IntegerFields, BooleanFields etc. etc.

When the form gets submitted for a new customer I want to export the data to an existing excel template, where cell names are B1 and value B2 for instance. So I was thinking to just give every field an 'cell position' attribute so I can just loop through the cells and easily assign each column their value, something like name = models.CharField(verbose_name='Name',max_length=30,'cell position' = 'B2'),

Would that be possible? If so or not, how would I go about doing this?

Samoht
  • 39
  • 6

1 Answers1

1

You are attempting to muddle together the data logic and business logic. You described one use case for that model: when it's to be saved. The cell position you had mentioned is only applicable to that use case and would be useless when you, for example, need to find a customer by its name.

Much senseful would be to put these constants to the file which is responsible for saving Customer to a excel file, like this:

class CustomerExcelExporter():
    CUSTOMER_FIELD_TO_FILE_CELLS = {
        "name": "B2",
        # ...
    }

    _worksheet: Worksheet
    _customer: Customer

    # ...

    def _fill_customer_own_fields(self):
        for field, cell in self.CUSTOMER_FIELD_TO_FILE_CELLS:
            self._worksheet.write(cell, getattr(self._customer, field)
Yevgeniy Kosmak
  • 3,561
  • 2
  • 10
  • 26
  • Ha! That makes much more sense, why didn't I think of that? Thanks a bunch! – Samoht Jan 10 '22 at 07:13
  • @Samoht glad to help :) – Yevgeniy Kosmak Jan 10 '22 at 10:05
  • I'm running into an issue while implementing this. My 'address' cell is split into the 'street' and 'house_number' field in my model. How do I merge these 2 into one variable to work with the `getattr`? Also: what package did you have in mind to write to the worksheet? I'm using openpyxl and it won't let me use `_worksheet.write` – Samoht Jan 19 '22 at 09:14
  • I'd advise you to split `CUSTOMER_FIELD_TO_FILE_CELLS` into `CUSTOMER_FIELD_TO_FILE_CELLS_PLAIN` and `CUSTOMER_FIELD_TO_FILE_CELLS_COMPLEX`. The second one could contain configuration like `{"address": ["C3", "C4"], ...}`. Then you can concatenate values from all items to obtain the `address`. – Yevgeniy Kosmak Jan 19 '22 at 10:41
  • No its the other way around. In the excel I have the column address, which is street + number. But street and number are both their own field in my model – Samoht Jan 25 '22 at 13:44
  • @Samoht then you have to come up with a different structure of dict, for example: `{"B2": {"fields": ["street", "number"], "regex": r"([^,]+),\s+(\w+)"}}`. Then you [can get needed data](https://prnt.sc/26j6hua) with `re`. However, it's a different question, and you can post it you need more detailed guidance. – Yevgeniy Kosmak Jan 25 '22 at 16:00