(Re) Learning how to code in Python with Django – Part 1: Setting up my dev environment

So I’ve decided to come back to writing about my periodic forays into coding, and I wanted to see if I can make some actual progress this time. A good place to start is to share my experience in setting up the environment in my Windows system for developing in Python using Django.

I’ve been doing my (on/off) tinkering with development on Windows Subsystem for Linux (WSL), and I must say that Windows has come a long way from the days where dual booting was required for Linux and Windows to co-exist. While it’s not perfect, WSL certainly makes it much easier to have my development environment in Windows, and I want to share a little bit about how I set this up.

Installing WSL

This entire part is pretty well documented by Microsoft. Still, for completeness, I’ve documented the steps here as well.

First, in Windows 10, search for the “Turn Windows features on or off” function in the Control Panel. This opens up a window and you can check the box next to the folder for “Windows Subsystem for Linux”. Click on “Ok”.

Alternatively, you can use this script from Windows Powershell with Administrator rights:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

This will likely prompt you to reboot your computer so let it reboot.

Once back into Windows, open the Microsoft Store and search for Linux. You can see there will be a few distributions (flavours) of Linux you can select. I chose Ubuntu. Click on the App, then click on Install.

Once installed, it needs to be initialized once, which you can access directly from the Windows Start menu. Just click on the app you installed just like every other app. You only need to do this once. Again, instructions are available on Microsoft Docs, but I will step through this very quickly.

Launching the WSL app of choice will typically open up a terminal (bash). The first thing they will prompt you is to create a Linux user account. Since WSL works entirely separate from Windows, you don’t have to use the same user ID as in Windows, and this can be set as you wish. It will also prompt you for a password twice.

Once done, it would be best to quickly update your WSL, and you do this by keying in the following command:

sudo apt update && sudo apt upgrade

This concludes the setup.

Python and Virtual Environment

One of the things I learnt about Python is that there are many variations in installation. It comes by default in Linux based OSes, like MacOS or Ubuntu, but needs to be separately installed for Windows. And then there are versions, with a lot of people still doing development on Python 2 even though Python 3 is the latest version. It’s worth noting that there are differences in the environment setup for the two, and you can even install BOTH at the same time in one OS. This is why I said there are many variations to the installation.

I searched for quite a number of resources to learn how to set this up, and one of the best articles on this is on the Mozilla Developer Network. You can check it out here.

Since we are using WSL, we will need to set it up there rather than in Windows. It probably already has some version of Python installed, and maybe even more than one. It’s a good idea to check this:

python -V

and

python3 -V

If it is installed, it will display the version. I would recommend at this point to use Python 3 as it’s the latest version.

Next step, is to install pip which is the Python Package Installer.

sudo apt install python3-pip

Now that we have pip installed, it’s time to setup the rest of the environment. Bear in mind the complications I mentioned above on various versions of Python and OSes, so it is recommended to always use a virtual environment setup in developing. Install it by using pip3 like this:

sudo pip3 install virtualenvwrapper

Now you will need to modify the .bashrc file (which sets up the options for bash and can be used to create shortcuts). We do this to complete the installation of virtual environment, allowing you to use this in the folder you are working on. The .bashrc file is typically located in the home folder (/home/username). Since WSL automatically puts you in Windows folders, you can quickly jump to it by using the following:

cd ~

It is not recommended to access and modify Linux files via Windows, so we will use the built in text editor to modify the .bashrc file. Use:

vim .bashrc

This launches Vim in the terminal window. Press the “down” arrow key until you hit the end of the file. Press “i” so that you can insert the text, move to the end of the last line, press “Enter” to create a new line. Then paste the following code with CTRL-V:

#VirtualEnvWrapper
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
export PROJECT_HOME=/mnt/c/development
source /usr/local/bin/virtualenvwrapper.sh

Do note that you should replace PROJECT_HOME value to the windows folder where you will be putting your development projects in. In the case above, it is in C:\development.

Using Vim to complete Virtualenv install.

Double check everything, and then press “ESC” to exit the “Insert mode” in Vim. The Insert word will disappear. Then type “:x” to quit Vim. It automatically saves the file.

Now we need to re-initialize .bashrc:

source ~/.bashrc

This loads a bunch of stuff and gets bash ready. Now you can navigate to your working directory (again, I recommend /mnt/c/development/django or something similar) and create a virtual environment (you can name it what you want).

mkvirtualenv my_django_environment

The command automatically creates the virtual environment and activates it. You will be able to notice this the bracketed environment name at the start of the bash prompt (left hand side).

Every time you start working on your development, you should activate the Virtual Environment first. You can practice / note these commands:

  • deactivate — Exit out of the current Python virtual environment
  • workon — List available virtual environments
  • workon name_of_environment — Activate the specified Python virtual environment
  • rmvirtualenv name_of_environment — Remove the specified environment.

Essentially, the two key ones are “workon” and “deactivate”. It is important to always be working on the correct Virtual Environment.

Installing Django

Now that we have setup Python and Virtual Environment, we can proceed to install Django. Do note, we do not install Django without first activating the Virtual Environment.

pip3 install django

That’s it. Now, let’s see if we can start a Django project. In this case, we use new_django_project as the folder where we store project files, and mydjangosite as the project name, but you can change it to anything you want.

mkdir new_django_project
cd new_django_project
django-admin startproject mydjangosite
cd mydjangosite
python3 manage.py runserver

That’s it, now we have setup Python and Django and we are ready to start building something great!

Python with Django pointers – Part 2: Apps, MVC(T) and Models

Django Apps

A Django project is typically formed from several Apps, each pertaining to a certain function within a website. Usually, I would expect to create one App for say, site updates and announcements, another App for commercial transactions with a shopping cart and checkout functions, yet another App for a forum etc.

Django comes with a built in Admin Site App, allowing trusted site administrators to quickly create, edit, delete and otherwise manage content. This is considered a common function that is required for just about ANY website, and covers things like management and authentication of users, display and management of forms, input validation, and translating all that into SQL statements for updates into the database. Having this by default really saves a lot of hassle when building a website and is a key feature available in the Django Framework.

Overall, since Apps can be made up of other Apps, it is easy to take a top down approach in designing the overall website functions, as breaking them down into Apps (or smaller Apps within an App) would make it much easier to architect the entire system. The team can then focus on individual Apps which will generate the functionalities required.

Key things for Apps:

  1. Use “python manage.py startapp name_of_app”
  2. Edit “settings.py” at the INSTALLED_APPS line with name_of_app.apps.Name_of_appConfig

Every App typically embodies the MVC structure which is what makes Apps so powerful because it is “self-sufficient” and can thus be replicated and utilized in different projects, with some minor tweaks done to the settings.

The MVC Structure

One of the coolest things about frameworks, is the ability to manage data separately from the logical layer, as well as the presentation layer. The MVC structure really makes things easier as you can split the management of all three layers making it cleaner and faster to make changes.

Edit: I previously stopped at describing Django as using the MVC concept above, but would like to correct it by saying that in there is a difference from a typical MVC structure as opposed to Django’s MVT structure. I think this explains the concept a lot better!

Models

Models are the foundation for data that drives your website. Every piece of dynamic data has to be defined in a model and stored in the database. Being able to manage how data is structured is quite typical in a framework, and Django does this very well by providing migration functions. Changes to the database level structure can be affected by using the “check”, “makemigrations” and “migrate” commands. This ensures consistency while developing where you can choose to update a column of a table for example by simply running these commands.

Of course, Django’s models can also have additional attributes which is on top of the database layer, making them extremely flexible.

Recap

So just a few key things for me:

  1. In models.py of an app, use following syntax
    class Name(models.Model):
    field = models.TypeField()
  2. Add this to Model Class to display human readable objects in models
    def __str__(self):
    return self.field
  3. To add a model to Django Admin, in admin.py, use following syntax
    from .models import Modelname
    admin.site.register(Modelname)
  4. For date, time and numbers data types (non-string), to allow blank fields, use
    field = models.TypeField(blank=True, null=True)

Python and Django pointers – Part 1: Using Virtualenv and Context Syntax

So I’ve decided to try (again) to learn how to code a full Web Application in Python using Django as the framework.

The number of false starts in my endeavour is enough to make me discouraged, but I just can’t totally let it go and I seem to keep coming back to it. Somehow, the desire to actually build something is still there, and I’m just hoping that this time I get somewhere. I’m blogging this experience in part to keep myself in check, and to also document some of my learnings so that I can always come back to it.

I would’ve loved to be coding on a MacBook, but I don’t have one and until I reach a stage where it would be more productive for me to get one, it would make more sense for me to continue using the existing Windows based laptops I have.

First, a few things I’ve (re)learned:

  1. Use pip to install virtualenv in Windows Subsystem for Linux (WSL or Windows Bash). Using Virtual Environment to manage Python Environments and versions are essential to making sure your development environment is consistent. It should essentially be part of your workflow.
  2. Context syntax for multiple variables is as follows: { ‘var_name’: ‘value’, ‘var_name2’: var}
  3. Context syntax for dictionary is as follows: {‘dictionary_name’: {‘var_name’: ‘value’}}
  4. Use “django.shortcuts import render” and then “return render(request, ‘template.html’, {‘context’: bar})”

Ok that’s about as far as I got. Considering it’s only a few hours in, with so much more to go, I really needed to put this down so I can make sure I keep going. At least it’s a start.

Next step is Apps and Migrations within a Project.