Home > Software design >  Create Multiple Instances From One Model Django
Create Multiple Instances From One Model Django

Time:07-31

I'm trying to understand how to create multiple instances on creation of a model in django. Eventually I want to create more than one but I'm just trying to get the signal to work at the moment. This is what I have so far that isn't working. I want it to create a duplicate of this model.

from datetime import datetime, timedelta
import django
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver


class BudgetTransaction(models.Model):
    """
    Individual transaction for Budget
    """

    transaction_types = [
        ('FI', 'Fixed Income'),
        ('FE', 'Fixed Expenses'),
        ('EC', 'Extra Cashflow'),
    ]

    frequencies = [
        ('one', 'one off'),
        ('wk', 'weekly'),
        ('fort', 'fortnightly'),
        ('mon', 'monthly'),
        ('yr', 'yearly'),
        ('day', 'specific day'),
    ]
    today = datetime.today().strftime('%Y-%m-%d')

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        help_text="Owner of the item"
    )
    transaction_type = models.CharField(max_length=40, choices=transaction_types, default=1)
    transaction_name = models.CharField(max_length=100, null=False)
    transaction_amount = models.IntegerField(null=False)
    next_date = models.DateField(null=False, default=today)
    frequency = models.CharField(max_length=20, choices=frequencies, default=1)
    complete = models.BooleanField(default=False)

    def __str__(self):
        return self.transaction_name

    class Meta:
        ordering = ['next_date']


@receiver(post_save, sender=BudgetTransaction)
def create_forecasted(sender, instance, created, **kwargs):
    if created:
        today = datetime.today()
        this_month = today.month
        months_left = 12 - this_month

        if sender.frequency == "mon":
            BudgetTransaction.objects.create(owner=instance.owner)

Thanks,

Mitchell

CodePudding user response:

I suggest to create a file called signals.py in the app next to models.py and place all your signals there as a cleaner structure I mean.

The @receiver decorator listens to the requests made to the server. If you make a viewset for this model with an endpoint to create a BudgetTransaction model. the receiver will work perfectly. But if this is done from django admin, I think the receiver won't work as you mentioned.

I think this may work here instead of @receiver. post_save.connect() as here https://docs.djangoproject.com/en/4.0/ref/signals/

CodePudding user response:

I solved this by using bulk_create rather than just create. I've put an example below to illustrate my change. It was receiving the request correctly with my original post however the code was just not functioning correctly once it was received. I could be wrong and I hope someone corrects this if it is wrong but I was initially getting a recursive error while using create() which I believe is because every time it ran it would resend a signal to create another item.

BudgetTransaction.objects.bulk_create([BudgetTransaction(
                owner=instance.owner,
                transaction_amount=1000,
                transaction_name=instance.transaction_name,
                transaction_type=instance.transaction_type,
                next_date="2022-08-08",
            )])
  • Related