1

I have a model and I want to get the method variable "row_count and column" count to put the value into the templates.

class Data(models.Model):
    """ Model of Data"""
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    document = models.FileField(upload_to='documents/%Y/%m/%d')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    amount = models.DecimalField(default=0, max_digits=6, decimal_places=2,
                                 blank=True, null=True)

    def calculate_amount(self):
        # wb = xlrd.open_workbook('media/' + self.document.name)
        wb = xlrd.open_workbook(os.path.join(settings.MEDIA_ROOT,
                                             self.document.name))
        worksheet = wb.sheet_by_index(0)

        # Show this value into templates
        row_count = worksheet.nrows
        column_count = worksheet.ncols


jmrcas
  • 83
  • 2
  • 2
  • 12

1 Answers1

1

You could use something like the following snippet, your model will now have 2 new attributes, row_count and columns_count, that can be called within your template and each of them will call calculate_amount to retrieve their values.

The if I added on calculate_amount prevents multiple calls to it to avoid multiple file reads and perhaps slowing your application.

class Data(models.Model):
    """ Model of Data"""
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    document = models.FileField(upload_to='documents/%Y/%m/%d')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    amount = models.DecimalField(default=0, max_digits=6, decimal_places=2,
                                 blank=True, null=True)

    def calculate_amount(self):
        if hasattr(self, '_row_count') or hasattr(self, '_column_count'):
            return
        # wb = xlrd.open_workbook('media/' + self.document.name)
        wb = xlrd.open_workbook(os.path.join(settings.MEDIA_ROOT,
                                             self.document.name))
        worksheet = wb.sheet_by_index(0)

        # Show this value into templates
        self.row_count = worksheet.nrows
        self.column_count = worksheet.ncols

    @property
    def row_count(self):
        self.calculate_amount()
        return self._row_count

    @row_count.setter
    def row_count(self, value):
        self._row_count = value

    @property
    def column_count(self):
        self.calculate_amount()
        return self._column_count

    @column_count.setter
    def column_count(self, value):
        self._column_count = value

Updated with property setters.

Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
  • thanks for your effort, there's an error, name row_count is not defined, Should I create signals to call the value? – jmrcas May 11 '20 at 21:34
  • @jmrcas How are you calling `row_count`? – Bernardo Duarte May 11 '20 at 21:44
  • It's okay now, thanks I learn new things. Just the page load too long because it reads again the file but I will figure it out. – jmrcas May 11 '20 at 21:48
  • just one question, Why did you rename it with underscore to variable? what is the purpose of that – jmrcas May 11 '20 at 21:50
  • @jmrcas I've renamed because I'm making an attribution to the instance variable, and I can't do that to a `@property`. Therefore making it `_row_count` and `_column_count` private variables by [convention](https://stackoverflow.com/a/1641236/7395911). Please consider upvoting if it helped! – Bernardo Duarte May 11 '20 at 21:53
  • @jmrcas You could [add a setter](https://stackoverflow.com/q/17330160/7395911) to the property – Bernardo Duarte May 11 '20 at 21:58
  • I tried to set the setter, but got an error. What is the value and code to set to the setter? thanks – jmrcas May 12 '20 at 01:15