I have a blog-like application with stories and categories:
class Category(models.Model):
...
class Story(models.Model):
categories = models.ManyToManyField(Category)
...
Now I know that when you save a new instance of a model with a many-to-many field, problems come up because the object is not yet in the database. This problem usually manifests itself on form submission, which can be neatly worked around with story_form.save(commit=False)
. What about a situation where there are no forms to speak of? In my case, I want to build an API to accept remote submissions. Since I like JSON, and a whole lot of other messaging in our company is in JSON (including outgoing messages from this server), I'd like to be able to receive the following:
{ "operation": "INSERT",
"values": [
{ "datatype": "story",
"categories": [4,6,8],
"id":50,
...
}
]
}
and implement a factory that converts the values to instances. But I'd like the factory to be as agnostic as possible to the type of operation. So:
{ "operation": "UPDATE",
"values": [
{ "datatype": "story",
"categories": [4,6,8],
"id":50,
...
}
]
}
should also be converted in the same way, except that INSERT ignores id and UPDATE gets the already existing instance and overrides it. (The remote submitter listens to a feed that gives it, among other things, the category objects to cache, so it can, and must, refer to them by id, but it doesn't have any direct communication with the database.)
My real question is: what's the most easiest consistent to inflate an instance of a Django model object that has a ManyToManyManager involved. As far as I can fathom, any insert of an object with a many-to-many field will require two database hits, just because it is necessary to obtain a new id first. But my current awkward solution is to save the object right away and mark it hidden, so that functions down the line can play with it and save it as something a little more meaningful. It seems like one step up would be overriding save
so that objects without ids save once, copy some proxy field to categories
, then save again. Best of all would be some robust manager object that saves me the trouble. What do you recommend?