Building a Project with Mezzanine

Building a Project with Mezzanine

In the first Mezzanine tutorial we explored various philosophies and approaches to web development using Mezzanine, Django, and Python. The emphasis of that tutorial was on why as much as what. We tend to be reflexive and impressionable in how we choose technologies: we want the new and shiny thing, or we want what others have, or we want what’s easiest. And in the rush to be in the game, to be at the forefront, to ride that turbulent wave of innovation, we often forget to ask deeper questions: why are we doing this, whom does it serve, what do we want? And now, as technologies increasingly drive social culture, the tools we use are themselves voices in that conversation. The technologies speak back to us: they shape us and drive us forward. And so — as I suggested in the first Mezzanine tutorial — our creativity, autonomy, and personal development are woven together with the technologies we use. And further: it would not be hyperbolic in the least to suggest that our very humanity depends on our mindful use of technologies. After all, we are the only species that is dependent on technology for survival. Technology is foundational to who we are. And yet, as we become increasingly dependent on digital technologies, we are also becoming less mindful about their use. This is the central dilemma we now face with digital culture: how to choose wisely in an environment ruled by impulse and reflexivity.

This tutorial continues the theme of mindful and intentional use of technology by exploring the steps required to create a first project with Mezzanine. In the previous tutorial we prepared our digital environment; here we populate that environment and bring it online. As before, the steps and procedures outlined here are not intended to be copied and pasted directly. Rather, my aim is to provide context and clarity, to highlight underlying implications, to ask why as much as what. We do enough mindless and routine stuff already. What we need is more wonder, creativity, and engagement (with technology, but also in general). Our activities with technology can provide these things: we just have to slow down enough to let it happen.

The Database

Anyone who uses digital technologies is intimately familiar with databases. I use the term intimately here in the same way that I would describe my relationship with my physical heart: I know it’s there, I recognize its vitality, I understand its essential role. I know that my life depends upon the healthy functioning of my heart. Yet I don’t see it, I am often not aware of it, and I would not be able to describe its actual form with anything approaching anatomical accuracy. I am intimately familiar with my heart, yet I hardly know it at all. It’s the same, for most of us, with databases. We use them constantly — on web sites, in social media, in our data storage and archiving — yet our knowledge about databases is tiny, and the systems themselves remain cryptic and arcane. That’s fine. After all, you don’t need to know anything about the semilunar valves in the heart in order to fall in love. But you do want (don’t you?) a strong and healthy heart.

The database is the heart of any content application for the Web (note that I have not used the metaphor of the brain: why not?). The database works invisibly, for the most part, storing and retrieving data in wonderfully dynamic ways. And, as you'd expect, we have many kinds of databases to choose from. Like everything else on the Web, the landscape of databases is ever-shifting and mercurial. But, if you look around, you'll find that many people have started to use one particular database for web development: PostgreSQL. (The first hurdle: how to pronounce it?) PostgreSQL is not necessarily orders of magnitude better than other databases; but for various technical reasons, many leading technology projects use PostgreSQL. It’s what we will use for our Mezzanine project. But we're not choosing PostgreSQL simply because it’s popular or technically proficient. No, our reasons have as much to do with philosophy and practice as they do with technical matters. We're choosing PostgreSQL for three main reasons (beyond its technical advantages): it’s open source (and free), as are all the parts of our Mezzanine project; it’s reliable, and it provides excellent documentation. These three aspects encourage us to support creativity and collaboration, enable us to feel comfortable that our content is safe and secure, and allow us to dive in and learn as we go. So, let’s do that:

sudo apt-get install postgresql postgresql-client

(Note that as with the previous tutorial, these instructions are for Ubuntu but should be easily adaptable to other systems). Depending on what is already installed on your system, various other packages (or no new packages, if you already have everything) will be installed after issuing the above command. You may also wish to install the graphical front-end for PostgreSQL, which might be a more comfortable environment for situations in which you need to actually look at the database structure or records (for me, that’s about once a year)

sudo apt-get install pgadmin3

A Philosophical Aside

Of course, you can also use Ubuntu’s graphical package manager to install any of these packages. It provides a shiny, friendly interface (with fireworks, no less) for package management. But there is at least one good reason to use the command line for this type of work: the command line is more truthful. Unlike graphical interfaces, which tend to hide various aspects of what’s going on behind the scenes, the command line shows you everything. All the weird, cryptic, geeky lingo; the errors and status messages; the unvarnished truth of what the system is doing — it’s all there on the command line. If you prefer truth to spin, if you choose depth over surface (and really, you should), then the command line is the place to do this kind of work. Sure, it might make you uncomfortable; but that’s what learning is: the joy brought about by careful and sustained immersion in discomfort.

Creating the Database

Upon installation, PostgreSQL creates its own default setup, which includes a user and database role that you will want to modify (to create your own password). We start with this command:

sudo -u postgres psql postgres

This command should deliver you to a new command prompt, which looks like this:

postgres=#

This is the psql command prompt, and is the main interface for working with the PostgreSQL system. Every time you activate this command prompt you will see this message: Type "help" for help. Go ahead and do it now.

postgres=# help

You can explore the PostgreSQL system thoroughly from this prompt (and you can also read the online documentation, which will probably be a more comfortable reading experience). For now, we need to complete a couple of simple tasks. First up: make sure you have a good password. As you may know, the current best practices for password creation involve long passwords and less emphasis on obfuscation (such as random strings of letters and numbers, which password-cracking systems are now good at interpreting). You can read more about these issues on the Dropbox blog, and you can use the strength meter on the Dropbox signup page to evaluate the security of your password. Your password does not have to be complex or hard-to-remember: it simply needs to be long enough. A single sentence with spaces removed typically makes an excellent password. For example, when I go to my bookshelf now, take a book off the shelf at random, and open to the first sentence I see, it is this: "He might find out how death could be avoided." (The book is The Epic of Gilgamesh) That’s a great sentence for a password: long enough (but not too long), and colorful enough to stick in my mind so that I don’t have to write it down. The Dropbox password meter says this password (with the spaces removed, but with the capitalization and punctuation intact) is "great!"

Remember: this password will be the key to all of your content. Choose wisely, then enter the following command, which will then ask you to enter the new password (naturally, insert your own password instead of my example):

\password postgres 
Enter new password: Hemightfindouthowdeathcouldbeavoided.
Enter it again: Hemightfindouthowdeathcouldbeavoided.

Excellent. You now have a postgres user whose password has been modified to suit your needs. To ensure that all has gone as planned, exit and restart psql:

\q 
sudo -u postgres psql postgres

You may also wish to create a new user, which will be a bit easier in the long run. If you create a new PostgreSQL user based on your system username (i.e. the name that shows up on the regular command prompt and which you use to login to Ubuntu), psql expects to find a database with that name. If such a database does not exist, psql will not let you in. So, to ensure that you can login to psql as a regular user, enter the following:

sudo -u postgres createuser --superuser $USER 
sudo -u postgres psql
postgres=# \password [enter your username]
Enter new password:
Enter it again:
\q
createdb $USER;

The Ubuntu community pages and the PostgreSQL documentation both offer excellent documentation about these steps. If you need more information, or to delve more deeply, those are good places to start.

And, finally, remember to exit psql before doing other work on the command line:

\q

It can be easy to forget that you are working from within the psql command environment, even though the command changes the prompt. If in doubt, just issue the exit command above, which won't do anything from a regular command prompt but will cause you to exit the psql command environment if you have inadvertently forgotten to do so.

With the above settings, you should be able to login to psql just by entering that command (when you do so, the psql command prompt will change from postgres to whatever your username is). Adding your own username to PostgreSQL also opens up the possibility of using that name, rather than the default postgres user, in the Mezzanine settings which follow. Technically there is no difference between these alternatives; which one you choose is completely a matter of preference.

Before we go much farther, we should review the command-line utilities provided by PostgreSQL. These are handy; they allow you to complete the most common database tasks without entering the psql command environment. Here are the commands I use most frequently:

createdb 
dropdb
pg_dump
pg_restore

The above commands do what you'd expect: create, delete (drop), backup (dump), and restore a database. As an example, the following procedure performs a backup, creates a fresh database, and restores the backup into the new database (use your database name in place of "dbname" and your chosen output filename in place of "outfile.dump"; the filename can be anything):

pg_dump -Fc dbname > db.dump 
createdb newdb #must be a new name
pg_restore -d newdb db.dump

The -Fc flag above refers to the custom format for backup, which, according to the pg_dump documentation, "is the most flexible format in that it allows reordering of loading data as well as object definitions. This format is also compressed by default." I don’t know much about the reordering of loading data or object definitions, but this procedure has worked perfectly for me every time that I've used it — which, in development, has been quite often.

But for our purposes right now, all we need is to create one database with one user. Whether you do this through psql and by using the postgres user, or by using your own username and working through the command line, the end result should be the same. Let’s assume you have created your own PostgreSQL user and can issue the createdb command from a regular command prompt. In that case, you just choose a name and enter the command. But take a moment to consider what name to use. I recommend that you not call your database test, or mezzanine, or anything too generic. Instead, use a distinctive name, and ideally a name that provides a context for sequencing. What do I mean by this? Here’s a sequence:

  • A New Hope
  • The Empire Strikes Back
  • The Return of the Jedi

Or, here’s another one:

  • The Fellowship of the Ring
  • The Two Towers
  • The Return of the King

And, if you want to be esoteric about it, here’s another one:

  • Hamlet
  • Macbeth
  • Prospero

Myth and culture are great places to find sequences. In turn, these types of sequences are used in the database world to make distinctions between different states or purposes of the database. Often, the terminology used is testing, development, and production. We're not necessarily going to follow the strict guidelines used by database developers, but we are almost surely going to have different databases as we build (and possibly break) and upgrade things. So, for the sake of simplicity in this tutorial, let’s use the sequence from Shakespeare:

  • Hamlet, for testing purposes. Shakespeare’s Hamlet is nascent, searching, tentative. A good name for starting out.

  • Macbeth, for development purposes. Shakespeare’s Macbeth is seasoned, strong, but still flawed. A good name for learning to be empowered, and learning about the limits of power.

  • Prospero, for deployment purposes. Shakespeare’s Prospero is wise, and ready to enter a new world ("release me from my bands, with the help of your good hands"). A good name for entering the wilderness of the Web.

Remember, technology cultures are not inherently distinct from literary cultures. The entire canon of human inquiry — all the arts and sciences — is one vast search for truth. We should not be too quick to leave behind the myths and stories of our past as we enter an uncertain future. After all, the past is the future, as all the myths say.

Alright, here we go:

createdb hamlet

Now the most technical part is done. All that remains is to tell Mezzanine about your database and build the project.

Installing the Project

A Mezzanine project is a collection of files that is typically built within a virtual environment (if you don’t know what that is, and you haven’t set one up, review the first Mezzanine tutorial ). These files enable the content management functionality, generate the web interface, and provide the general application framework for a Mezzzanine site. And, in keeping with Mezzanine’s emphasis on simplicity and efficiency, the method of creating a project involves one command (as usual, don’t enter it yet!):

mezzanine-project someproject

In the above command, someproject is simply a placeholder for whatever you choose to call your project; mezzanine-project is the actual command. The question of what you call your project is important: you cannot use a name that is already in use by Mezzanine, Django, or any Python module. So, for example, you cannot call your project test or mezzanine. Thankfully, you don’t need to know anything about potential conflicts. If you choose a disallowed name, the command will let you know that the name "conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name." Fair enough.

Where to put the project? It’s up to you; there are no firm rules about this. Some people prefer directories intended for online applications (such as /var/www), whereas others prefer the home directory (where it is usually easier to get at things and to back them up). I place my projects in my home folder, in one of the directories that are automatically backed up by Dropbox or Ubuntu One.

You can run the mezzanine-project with the full path to your intended project, or you can enter the parent directory of the project first, then run the command without the path. this (with project name Ariel):

mezzanine-project /home/me/Dropbox/ariel 
Or:
cd /home/me/Dropbox
mezzanine-project ariel

Make sure you are working inside your virtual environment (use the workon command), then go ahead and run mezzanine-project to create a project. You won’t see any feedback from the command, but you will likely see a short pause while the files are copied.

Excellent. Now, navigate to the directory of your project. In the main directory, you will see a file called local_settings.py. Go ahead and open that file with a text editor (Vim, Emacs, Gedit, whatever; just don’t use a word processor). Fill in the main entries (engine, name, user, password, host, port) with the settings we created previously. Like this:

DATABASES = { 
"default": {
# Ends with "postgresql_psycopg2", "mysql", "sqlite3" or "oracle".
"ENGINE": "django.db.backends.postgresql_psycopg2",
# DB name or path to database file if using sqlite3.
"NAME": "hamlet",
# Not used with sqlite3.
"USER": "me", # Use your actual username.
# Not used with sqlite3.
"PASSWORD": "Hemightfindouthowdeathcouldbeavoided.", # Use your actual password.
# Set to empty string for localhost. Not used with sqlite3.
"HOST": "localhost", # I have found that placing "localhost" here is required in some cases.
# Set to empty string for default. Not used with sqlite3.
"PORT": "5432",
# See below.
}

See that last entry, the PORT entry? Sometimes there is a gotcha with PostgreSQL, on some systems, in which the default port is disabled. You can check this on your own system by opening the postgresql.conf file. This file might live in several different places; try /etc/postgresql/9.1/main first. Once you have located this file, open it up and look near the end. You will see some entries like these:

# - Connection Settings - 
listen_addresses = '*'
# what IP address(es) to listen on; 
# defaults to 'localhost', '*' = all 
port = 5432
# (change requires restart)

Is there a hash sign (#) before the word port? If there is no hash sign, you are already good to go. But if it’s there, take it out (so that the entry looks the same as above), save the file, and restart PostgreSQL:

sudo service postgresql restart 
Or, if you're old-fashioned:
sudo /etc/init.d/postgresql restart

One other thing you may wish to do is to set your timezone. This setting is located in settings.py (not local_settings.py, above, but in the same directory). I live in Vancouver, so my setting looks this (with the quotes):

TIME_ZONE = "America/Vancouver"

Done. There are a number of other settings that we will explore in the next tutorial, but for now all we need to do is fire up the Mezzanine service that will populate the database and initiate the project. Run this command within the same directory as your local_settings.py and settings.py files:

python manage.py createdb

manage.py is the main operational interface for Mezzanine. You will learn more about it later (a bit farther down, and in the third tutorial). For now, you just need the first command above, which will yield quite a few line entries like these:

Creating tables ... 
Creating table auth_permission
Creating table auth_group
...
Creating table django_comment_flags

Then you will be asked to create a super-user (answer yes), to provide details that user, and to answer a few more questions. Just follow the prompts and accept the default answer for anything that you don’t understand or about which you are unsure. You can always change (most of) these settings later.

That’s it. You're done. Your Mezzanine project is ready. Go home, as Ferris Bueller said.

Well, maybe just one more thing.

Moving to the Browser

Run this:

python manage.py runserver

Follow the instructions and open your browser to http://127.0.0.1:8000/admin/. You should see the Mezzanine administration pages. Now you're done.

What’s Next?

In the next tutorial we’ll explore the administration interface, the public-facing site, and the various settings that help Mezzanine work better with other services and applications. And we will try to remember, as we work this geeky gear, that what we’re building is not just web applications. We're building projections of our identities and creative aspirations into the digital sphere. To steal the metaphor from the first tutorial, the real project we’re working on is a project called ourselves.

Update: the third tutorial is here.

← First Steps with Mezzanine What Students Want →

COMMENTS