Home > Net >  Creating an "incomplete" Django class for a user to fill in
Creating an "incomplete" Django class for a user to fill in

Time:01-16

I have a database representing financial transactions. Columns representing payee and category are non-optional.

However, part of my app's functionality will be to ingest external spreadsheets of transactions which do not already have payee and category information. I would then populate a form where the user will select correct payees and categories through drop-down menus, and then save the completed information to the database.

Is the correct approach to simply create two separate but equivalent classes (see below)? Or is there some way to make one a sub-class to another, despite the fact that one is connected to a database and the other is not.

# An initial class representing a transaction read from an Excel sheet
# Payee and category information are missing at this stage, but will be filled
# in by the user later on

class TransactionFromSpreadsheet:

    def __init__(self, date, amount):
        self.date = date
        self.amount = amount
        self.payee = None
        self.category = None

# The Django class that will be instantiated once all the user has completed all
# necessary information

class Transaction(models.Model):
    date = models.DateField()
    amount = models.DecimalField(max_digits=14, decimal_places=2)
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
    payee = models.ForeignKey('Payee', on_delete=models.CASCADE)

CodePudding user response:

One could use optional foreign keys and a custom manager to provide an easy way to query the "incomplete" or "complete" transactions.

class TransactionQueryset(models.query.QuerySet):
    def complete(self):
        return self.filter(category__isnull=False,
                           payee__isnull=False)

    def incomplete(self):
        return self.filter(category__isnull=True,
                           payee__isnull=True)


class TransactionManager(models.Manager):
    def get_queryset(self):
        return TransactionQueryset(self.model, using=self._db)

    def complete(self):
        return self.get_queryset().complete()

    def incomplete(self):
        return self.get_queryset().incomplete()


class Transaction(models.Model):
    date = models.DateField()
    amount = models.DecimalField(max_digits=14, decimal_places=2)
    category = models.ForeignKey('Category', on_delete=models.CASCADE,
                                 blank=True, null=True)
    payee = models.ForeignKey('Payee', on_delete=models.CASCADE,
                              blank=True, null=True)

    objects = TransactionManager()

And if you now need an incomplete transaction you could easily get these in a view:

def view_incomplete(request):
    incompletes = Transaction.objects.incomplete()
    return render(request, 'incomplete_template.html',
                  {'incompletes': incompletes})

It is now very comfortable to gather all heavily used filter conditions in the queryset and manager class.

And if you have non complementary filter conditions you could even chain the manager functions.

  • Related