(WIP) Cdodge/shopping cart rewrite

OK, I see why this is happening. There's a circular dependency happening if we have it up at the top. There will need to be some code refactoring to move that function into models.py (which I think if the better place for that). I'd do that refactoring now, but the problem is that save_registration_code uses a "random string generator" method that is also being refactored in a separate PR (for a different feature).

We'll have to swing back to this particular comment after all these PR's land.