Search code examples
pythondjangodjango-import-export

Django import export edit queryset before export


I'm trying to calculate the pending amount via models and export result in the csv. But the csv shows an empty column for amountpending

class FinancePendingResource(resources.ModelResource):

    invoiceNumber = Field(attribute='invoiceNumber', column_name='Invoice Number')
    student = Field(attribute='student', column_name='Student')
    Schedule = Field(attribute='Schedule', column_name='Schedule')
    TotalAmount = Field(attribute='TotalAmount', column_name='Total Value(PKR ₨)')
    issueDate = Field(attribute='issueDate', column_name='Issue Date')
    dueDate = Field(attribute='dueDate', column_name='Due Date')
    amountPaid = Field(attribute='amountPaid', column_name='Amount Paid (PKR ₨)')


    class Meta:
        model = FinancePending
        import_id_fields = ('invoiceNumber',)
        fields = ('invoiceNumber', 'student', 'amountPaid', 'issueDate', 'dueDate', 'Schedule', 'TotalAmount',
                  'AmountPending',)
        exclude = ('id',)
        skip_unchanged = True
        report_skipped = True

        def before_export(self, queryset, *args, **kwargs):
            amount_paid = FinancePending.objects.values_list('amountPaid', flat=True)
            amount_paid = list(amount_paid)
            total_amount = FinancePending.objects.values_list('TotalAmount', flat=True)
            total_amount = list(total_amount)

            # total - paid
            TotalFee = [float(s.replace(',', '')) for s in total_amount]
            AmountPaid = [float(s.replace(',', '')) for s in amount_paid]

            def Diff(li1, li2):
                return (list(set(li1) - set(li2)))

            amount_pending = Diff(TotalFee, AmountPaid)

            finance_pending = FinancePending()
            i = 1
            while i <= len(amount_pending):
                FinancePending.objects.filter(invoiceNumber=i).update(AmountPending=str(amount_pending[i]))
                i = i + 1

            queryset.refresh_from_db()

Solution

  • Assuming that you have the data to compute amountPending already in the dataset, perhaps you don't need to read from the DB: you could calculate the amount by processing the dataset in memory. This could be done in after_export(). Then you can added the computed column to the dataset.

    Perhaps tablib's dynamic columns can assist in adding the amountPending column:

    import decimal
    import tablib
    
    headers = ('invoiceNumber', 'amountPaid', 'totalAmount')
    rows = [
        ('inv100', '100.00', "500.00"),
        ('inv101', '200.00', "250.00")
    ]
    
    def amount_pending(row):
        return decimal.Decimal(row[2]) - decimal.Decimal(row[1])
    
    data = tablib.Dataset(*rows, headers=headers)
    data.append_col(amount_pending, header="amountPending")
    print(data)
    

    This will produce the following:

    invoiceNumber|amountPaid|totalAmount|amountPending
    -------------|----------|-----------|-------------
    inv100       |100.00    |500.00     |400.00       
    inv101       |200.00    |250.00     |50.00