2

I have a model Movie and a Model DefaultMoviePriceFor which saves the default prices for a specific genre:

class Movie(models.Model):
    name = models.TextField('name', null=True)
    genre = models.TextField('genre', null=True)
    price = models.IntegerField('price', default=0)

class DefaultMoviePriceForGenre(models.Model):
    genre = models.TextField('genre', null=True)
    price = models.IntegerField('price', default=0)

Now I would like to fill up Movie.price with the default price of the Movie.genre everytime an object of Movie is instantiated.

Is there any good way to do so? I have SQL triggers in my head, they could do that, don't they? How is it done in django?

3
  • Make the price nullable, and given it is null, fetch the relevant DefaultMoviePriceForGenre. Commented Jan 14, 2019 at 23:34
  • @WillemVanOnsem but where? Is there any method which is called when the model gets instantiated? Commented Jan 14, 2019 at 23:49
  • Unrelated to the "how do I call custom code on save" part of the question - you'll do better if you make genre a model as well and use ForeignKey relations to ensure that the data is properly consistent. Commented Jan 15, 2019 at 0:05

1 Answer 1

2

One way to do this is with the pre-save signal. This will be fired immediately before any instance of the model is saved, and will received a created boolean arg that will let you set the price only if the object is new.

There's also a post-save signal if for some reason you want to do it after saving, EG because your behavior depends on the new instance's PK. But pre-save should work here.

Alternatively, you can override the model class's save method. https://docs.djangoproject.com/en/2.1/topics/db/models/#overriding-model-methods

See this answer for some discussion of the pros and cons of the two approaches: Django signals vs. overriding save method

This is all assuming the desired behavior is exactly as described - look up the current default price of the genre when the instance is created and preserve it independently of future changes to the genre. If you want to do something more flexible - EG say "horror movies cost X now unless overridden, but if I change the default genre price later they should all update" you might be best served with a method on the Movie class that computes the price based on current state rather than setting it at creation and breaking that connection. But it depends what you want.

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

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.