I have just finished my first Django application as my CS50x final project (Yay!). It's a meal planning and shopping list application. Thrilling eh?
Actually, I am pretty thrilled as it happens.
It's taken the best part of a month to get from blank screen to deployment. And that's while working full time in a completely unrelated job.
I knew very little about Django at the outset, having only worked through the obligatory 'Hello World' and a basic blog tutorial. Tutorials are great but it's only when you start building your own projects that you really learn the workings of a framework or language. On more than one occasion I thought I had bitten off more than I could chew and seriously considered jacking it all in. I'm glad that I persevered though: I'm pretty pleased with the finished article.
Because of the nature of the application, I spent a lot of time wrestling with Django's form-handling capabilities. HTML forms are never easy to work with. Django's built-in Forms module has its own intricacies, but overall I think it greatly simplifies the process.
I also spent some time getting my head around Django's database abstraction API. This is an ORM tool that hugely simplifies interaction with a database. For this project I stuck with the SQLite database that effectively comes bundled with Django.
My wife and I switched to a vegan diet almost a year ago. One of the immediate practical effects was that we started to cook a lot more of our own meals. Clearly, before you can cook a meal you need to have all of the ingredients to hand so cooking also means shopping for ingredients. Before you can go shopping you need a list of ingredients to buy.
Sometimes(!) I actually enjoy cooking. But making a shopping list and going to the supermarket to buy the ingredients is a royal pain in the arse! So, having a brain that naturally leans towards problem-solving, I wondered if I could program something to remove a bit of the pain from the process.
The app is based on the fundamental premise that a shopping list is composed of two elements:
- items that you need to prepare the meals that you plan to eat over the coming days; and,
- general 'stock items' to replenish your cupboards.
The app enables you to:
- build a database of meals, each with a list of items that you need to buy to cook the meal; and,
- build a database of items generally, some of which are marked as favourites (ie. the things that buy regularly)
Each of the items held in the database is associated with a storage location (ie. where you store that kind of item at home) and a shop department (ie. where you find that item in the supermarket). The storage locations and shop departments can be sorted according to the order that you visit them when making a list (storage locations) and navigating the supermarket (shop depts.). The idea there is that the order you add items to your list is probably not the same as the order you put things in your basket.
To compose a new list:
- Choose the meals you plan to cook over the next few days. A list of items that you need is then created in storage location order. The list contains all of the items you will need to prepare the chosen meals.
- A list of the stock items (that you have marked as favourite) is then created automatically, again in storage location order.
- Those separate lists are then combined and presented to you with tick boxes so you can do the tour of your cupboards and tick the items that you need to buy. (You might have some meal ingredients already in stock. eg. the list might tell you that you need garlic for the curry that you chose in step 1 but when you look in the fridge you see that you have plenty of garlic so you don't tick it)
- Your final list is presented to you in shop department order (you having previously adjusted the order of departments according to your supermarket). As you put an item in your basket, tap its entry on the list and it is greyed-out to show you've got it.
And that's it!
I deployed the app, via Git Hub, to Python Anywhere, the service used by the Django Girls in their blog tutorial. They have a free 'beginner' account which supports SQLite databases. Heroku was another hosting option but it looks like they somehow purge their file system daily so SQLite, being a file-based database, is not an option there.
I did a small amount of CSS styling. (If you look at the app you will see that visual design is not my strongest suit! Haha!) It's designed to work on mobile/tablet first and foremost; not many people take their laptop shopping.
So, next steps for this app are: drag and drop, as mentioned in the last paragraph, and adding user accounts so that it can be personalised for different users.
After almost giving up mid-project, I'm very pleased with the result of my first tango with Django. I would welcome any feedback; even if it's good feedback! You can see the finished article at: http://shoplist.pythonanywhere.com.