Home > Net >  Django update_or_create using foreying key objects
Django update_or_create using foreying key objects

Time:02-10

My app have two models, PortfolioAsset and Transction.

I am trying to use update_or_create in the transaction to find if the object PortfolioAsset exist with the selected parameters. If it exist to update, if not to create.

But i am getting this error:

Cannot assign "(<PortfolioAsset: PortfolioAsset object (11)>, False)": "Transaction.portfolio_asset" must be a "PortfolioAsset" instance.

This was the exisiting object that i would like to update in this example.

PortfolioAsset

class PortfolioAsset(models.Model):
    portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, default=1)
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
    shares_amount = models.DecimalField(max_digits=18, decimal_places=0) 

    def validate_unique(self, *args, **kwargs):
        super().validate_unique(*args, **kwargs)
        if self.__class__.objects.\
                filter(portfolio=self.portfolio, asset=self.asset).\
                exists():
            raise ValidationError(
                message='This asset already exists in this portfolio.',
                code='unique_together',
            )

and Transactions:

class Transaction(models.Model):
    OrderChoices = (
        ('Buy', 'Buy'),
        ('Sell', 'Sell'),
    )
    portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, default=1)
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE, default=1)
    portfolio_asset = models.ForeignKey(PortfolioAsset, on_delete=models.CASCADE, editable=False)
    shares_amount = models.DecimalField(max_digits=18, decimal_places=0)
    order = models.CharField(max_length = 8, choices = OrderChoices)        

    def save(self, *args, **kwargs):
        self.portfolio_asset = PortfolioAsset.objects.update_or_create(portfolio=self.portfolio, asset=self.asset)
        if self.order == 'Buy':
            self.portfolio_asset.shares_amount  = self.shares_amount
        if self.order == 'Sell':
            self.portfolio_asset.shares_amount -= self.shares_amount
        self.portfolio_asset.save()
        super(Transaction, self).save(*args, **kwargs) 

What am i doing wrong? Thanks

CodePudding user response:

update_or_create..[Django-doc] returns a tuple: the object, and a flag that indicates whether or not it was created.

So you will have to capture the object first like this:

self.portfolio_asset, created = PortfolioAsset.objects.update_or_create(portfolio=self.portfolio, asset=self.asset)
                      # ^^^ Add this
  • Related