Lets say that we are getting POSTed a form like this in Django:
rate=10
items= [23,12,31,52,83,34]
The items are primary keys of an Item model. I have a bunch of business logic that will run and create more items based on this data, the results of some db lookups, and some business logic. I want to put that logic into a save signal or an overridden Model.save()
method of another model (let's call it Inventory
). The business logic will run when I create a new Inventory
object using this form data. Inventory will look like this:
class Inventory(models.Model):
picked_items = models.ManyToManyField(Item, related_name="items_picked_set")
calculated_items = models.ManyToManyField(Item, related_name="items_calculated_set")
rate = models.DecimalField()
... other fields here ...
New calculated_items
will be created based on the passed in items which will be stored as picked_items
.
My question is this: is it better for the save()
method on this model to accept:
- the request object (I don't really like this coupling)
- the form data as arguments or kwargs (a list of primary keys and the other form fields)
- a list of Items (The caller form or view will lookup the list of Items and create a list as well as pass in the other form fields)
- some other approach?
I know this is a bit subjective, but I was wondering what the general idea is. I've looked through a lot of code but I'm having a hard time finding a pattern I like.
Clarification:
OK, so the consensus is that it should go into a different function on the model, something like inventory.calculate(...)
which will then create everything, do the business logic, etc... That's good to know. My question remains: where is the best place to look up the form data into db objects? Should the caller of this function convert primary keys to database models or should the model methods accept primary keys and do it themselves? It's something that I want to do the same way project-wide.
Clarification 2:
OK so now there is some disagreement as to wether overriding save
is ok or not.
When you get a form submission for a simple CRUD type operation, you pass the models and values as arguments to Model.objects.create(...)
or override save
or use signals or whatever.
I think the core of my question is this:
If the form submission has related models used for business logic, then you need to write some business logic into your model layer. When you do this, where should it go and should that method accept a list of objects or a list of id's? Should the model API's accept objects or id's?