13

I was studying some Django, and came across a small problem.

I am looking for a way to make suit_length equal to customer's height by default. This kind of code works for me:

    class Customer(models.Model):
        name = models.CharField(max_length=20)
        height = models.IntegerField(default=170)

    class Suit(models.Model)
        customer = models.ForeignKey(Customer)
        suit_design = models.CharField(max_length=100)
        suit_length = models.IntegerField(default=0)
        def get_height(self):
            self.suit_length = self.customer.height
            return

But every time I create a new Suit its default suit_length = 0, and I have to run get_height() to get what I want. Is there a way to default suit_length to customer.height and to avoid running get_height() every time I create a new Suit? I am probably looking for smth like this:

    class Customer(models.Model):
        name = models.CharField(max_length=20)
        height = models.IntegerField(default=170)

    class Suit(models.Model)
        customer = models.ForeignKey(Customer)
        suit_design = models.CharField(max_length=500)
        suit_length = models.IntegerField(default=lambda:self.customer.height)

But this code doesn't work.

2
  • as long as your customer default height is 170, why don;t you make the suit_Lenght 170 as well? Commented Apr 6, 2014 at 10:15
  • Good point, but let's pretend there is no default height. Commented Apr 6, 2014 at 10:19

2 Answers 2

9

Django uses the save() method to actually save the data. You may overwrite it like so:

class Suit(models.Model):
    def save(self):
        if self.suit_length == 0:
            self.suit_length = self.customer.height
        super(Suit, self).save()

It is not overwriting the default, but it achieves your goal.

Sign up to request clarification or add additional context in comments.

Comments

1

You want an invariant to be true at run-time, which is that the initial length of a Suit is equal to the height of a Customer.

Doesn't the pythonic way to do this involve __ init __() ?

    class Suit(models.Model)
        customer = models.ForeignKey(Customer)
        suit_design = models.CharField(max_length=500)
        suit_length = models.IntegerField(default=lambda:self.customer.height)

        def __init__(self, args, kwargs):
            super(models.Model, args, kwargs)
            if kwargs['customer']:
                self.customer = kwargs['customer']
                # this creates the invariant
                self.suit_length = self.customer.height  
            else:
                raise ValueError("Must have a customer before constructing a Suit")
            # More code for suit_design, etc.
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.