MagicLAMP
MagicLAMP

Reputation: 1082

Two foreign key fields, exactly one is set to a value, the other null in django model with MySQL database

I have a django model with two foreign key fields, one that points to product, the other points to portfolio in the code below. Exatcly one of these should be set for each Lca record. I know I can do this with MySQL triggers, but I was wondering if there was a way to make this conditional save in django

class Lca(models.Model):
    product             = models.ForeignKey(product, null=True, blank=True)
    portfolio           = models.ForeignKey(portfolio, null=True, blank=True)
    carbon_price        = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    name                = models.CharField(max_length=255, blank=True)
    total_footprint     = models.IntegerField(blank=True, null=True)
    calculation_type    = models.CharField(max_length=9)
    total_cv            = models.DecimalField(max_digits=10, decimal_places=0, blank=True, null=True)
    source              = models.CharField(max_length=255, blank=True)
    date_from           = models.DateField()
    date_to             = models.DateField(blank=True, null=True)

    def __unicode__(self):
        return self.name
    # end __unicode__
# end

Upvotes: 5

Views: 997

Answers (3)

Joel Crocker
Joel Crocker

Reputation: 155

I would recommend adding a model clean() method for any custom validation you want to add. Model clean methods are called automatically by ModelForms, but not by save(), so you may need to call the model full_clean() method yourself and handle ValidationErrors if they occur, depending on your use case.

See the Django documentation for more information on Model.clean().

Upvotes: 0

adrien
adrien

Reputation: 146

You can use clean forms validations if you requested your data from a form.

Upvotes: 0

jonafato
jonafato

Reputation: 1605

You can override the model's save method:

def save(self, *args, **kwargs):
    if self.product and self.portfolio or not self.product and not self.portfolio:
        raise ValueError('Exactly one of [Lca.product, Lca.portfolio] must be set')

    super(Lca, self).save(*args, **kwargs)

Note that this method is not applicable to bulk_create.

Upvotes: 8

Related Questions