0

I need some ideas to solve the following issue, maybe with some design pattern or another approach in my current architecture.

My app's backend is entirely developed in Django framework and has five current models (no matter relationships between them):

  • Product(id, product_name, product_category, product_code)
  • Customer(id, customer_name)
  • Account (id, account_code, account_name)
  • City(id, city_name)
  • User(id, email, user_name)

In first place, I need to add a new model to dynamically and easily create Transactions with any possible combination of the above models in the following way:

  • Example 1: Transaction(id, product, customer, year, month, amount)
  • Example 2: Transaction(id, account, year, month, amount)
  • Example 3: Transaction(id, account, city, year, month, amount)
  • Example N: Transaction(id, product, user, year, month, anount

As you can see, my Transaction model has a few static fields (year, month, amount), but the other fields depends on a random customization according the use case.

I've thought something like Transaction(id, dynamic_field_1, dynamic_field_2, dynamic_field_3, year, amount), but how can I make it dynamically? Is there some design pattern or properly way to do this?

In addition, I need that those fields have been validated from the previous models. For example:

Transaction(id, product, customer, year, month, amount):

  • validate that product exist in the database
  • validate that customer exist in the database

How can i make this approach?

Thank you!

  • I would take a look at [generic relations](https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/#generic-relations) – t0bi Jul 30 '18 at 20:11

1 Answers1

0

If you can fix source code when add transaction type, I think performance is the best
You can make Transaction model with every possible column using nullable, and when the new transaction created, you can validate isNull about the needed field.

class Transaction(models.Model):
    transaction_id = models.AutoField(primary_key=True)
    transaction_product = models.ForeignKey('Product', on_delete=models.CASCADE, blank=True, null=False)
    transaction_customer = models.ForeignKey('Customer', on_delete=models.CASCADE, blank=True, null=False)
    transaction_year = models.CharField(max_length=32, null=True, blank=True, db_index=True)
    transaction_month = models.CharField(max_length=32, null=True, blank=True, db_index=True)
    ...
    ...

If you need to add transaction type on web admin page
I think You can make TransactionExtra model has many2many relation with Transaction. like this.

class Transaction(models.Model):
    transaction_id = models.AutoField(primary_key=True)
    transaction_extra = models.ManyToManyField('TransactionExtra', db_index=True)

class TransactionExtra(models.Model):
    transaction_extra_id = models.AutoField(primary_key=True)
    transaction_extra_name = models.CharField(max_length=32, index=True)
    transaction_extra_value = models.CharField(max_length=512)
EunChong Lee
  • 189
  • 1
  • 5