You said the data may come from the db, or it may come from somewhere else. I was about to say that if the data didn't come out of the db then it must be a new record, until I remembered a report I did where there's a single select to get all the data. For each row of the results I create an object by passing in all the data, so that I can then use the output formatting methods of the object.
Hmm, I've been preaching lately that our object constructors should be more lightweight, only hitting the db as much as we need to for the current operation. (Our worst case is an object that has at least six different init methods depending on which data you're working with, and someone decided it would be easier to just call all of them in the constructor.)