m

I was looking for documentation to learn jQuery Mobile and found this great tutorial written by Stéphanie Walter. It covers the front-end of a mobile application using jQuery Mobile.

Every application needs of a front-end and a back-end development. If we simplify the concepts we could say the front-end part is responsible of the user interface and the back-end is responsible of the database access and processing of the data.

I have decided then to write the server-side code for this Restaurant Picker application. After asking for permission to Stéphanie to use her example and front-end code I took the chance to write this Django tutorial. This tutorial doesn’t cover the deployment to production and everything is treated in a development environment.

Django is an open source web framework written in Python which follows the model–view–controller (MVC) architectural pattern. If you know Python I find it quite easy to start to code a web application, most of the most used functions are automated and you can use them out of the box. Besides, it has a big community and clear documentation.

As I said I will use the Restaurant Picker example and the code generated in the tutorial I linked above. You may want to read those specifications since those are the ones we are going to follow. As a summary in the image below you can see the different screens of our application:

screens

Let’s start to code. I will assume you already have django installed, if not you can follow the installation guide.

Setting up the project

The first thing we need to do is to create our project and application folder structure. One project can have multiple applications. The idea behind this is to follow the DRY (Don’t Repeat Yourself) principle so that you can isolate applications in order to be reused by other projects. In our example we will have one project with only one application.

To create our Django project called rest_picker type the following command in the console:

As a result we will get:

We will define the global parametres of the project in the files above later.

To create our aplication, called restaurants inside our rest_picker project we move into the root project folder and once there we must type in the console:

A new directory is created called restaurants with specific files for this application.

Now we need to create a database. There are many options when choosing a database (postgres, mysql, oracle, …), we will go for the easiest one for Django, SQLite3. Django will create it for us automatically once we define it in the settings.py file. If you have choosen one of the other options you will need to create the database first by yourself.

Let’s edit the settings.py file for a SQLite3 database and define the TIME_ZONE:

Remember of changing the path to the one in your machine.

Models

Now we need to define the database schema for our application. We do this defining Django models. Each model is a Python class that subclasses django.db.models.Model. Each attribute of the model represents a database field.

Let’s remember the screens to think how many tables and which fields our app needs.

  • A screen listing kind of foods
  • A screen listing towns
  • A screen listing restaurants
  • A screen with the details of the restaurant: name, description, what to eat, web site, phone number, address, postal code, a url for google maps, number of stars, food and town

We need then a table for kind of foods, a table for towns and a table for restaurants. The fields food and city of the restaurant table will be linked in a many2one relation to the Food and Town tables.

We want to display an image with the food, and also an image for the restaurant and an image of a map with the restaurant location. We need to store those images in the server and store the path in the database so we can retrieve them when needed.

This is how the models.py file must look like:

We overwrite the __unicode__() method to return a human-readable representation of the model instead of str(obj) that is what is defined by default.

The menu field will store a list of food and drinks that are offered in the restaurant. This list should be entered separating elements with semicolons so that we can process it later to display it in the correct way.

The ImageField needs of a more detailed explanation. The upload_to parameter defines a relative path to the MEDIA_ROOT parameter defined in the settings.py file. We will upload the images to a media/image/ folder inside the root project. We need to create those folders, getting the folder structure detailed below:

We edit now the settings.py file:

Remember of changing the path to the one in your machine.

MEDIA_ROOT defines the absolute path where the image will be stored. Since we have defined the upload_to attribute of ImageField as images/, the images will be stored under /home/yaiza/dev/rest_picker/media/images/. MEDIA_URL defines which url serves the media file, we will understand this parameter better when we see the urls and views files.

Before running the command to create the tables we need to add our application to the list of INSTALLED_APPS in the settings.py file. We will uncomment the django.contrib.admin line as well that is responsible of generating the automatic admin interface that we will see later. We can leave the ones that are activated by default as they are since they define basic operations as authentication, a session framework, a framework for managing multiple sites, …

We are ready to run the command to generate the tables in our database:

This command looks for new applications in the list of INSTALLED_APPS in the settings.py file and creates the tables in the database. Since it is the first time that we run it and we chose SQLite3 as our database it will ask for the creation of a superuser. Go ahead and create that superuser.

[Note: The syncdb command only creates new tables but it doesn’t notice changes in an existing model, hence, it doesn’t modify existing tables. To do this easily you may want to have a look at South, a tool for database migrations for Django applications.]

We have already created the database schema for the application.

Admin Interface

By default Django provides an admin interface that is reading the models that we have just created. We just need to define which url is going to serve our admin interface. We do that through the rest_picker/urls.py file:

This file defines the URLconf module that maps urls with given Python code (views) or HTML templates. The path to get to this file was defined by default in our settings.py file when we created the project (ROOT_URLCONF = ‘rest_picker.urls’). You can change this if you want to.

The first argument of the patterns function is a string prefix (we are not using this prefix for now, we will explain it later), the following ones are url functions. The url function accepts two arguments minimum: a regular expression and either the view that must be called or a redirection to other URLconf module, when that url is met. In this case, we are referring to another URLconf module using the include function. This module comes by default with Django.

If we look at the regular expression r’^admin/’ this means that adding admin/ to our base url we will get the admin interface. Let’s check it.

Django comes with a lightweight development web server on the local machine. By default, the server runs on port 8000 on the IP address 127.0.0.1 (localhost). You can pass in an IP address and port number explicitly. (Django recommends not to use this server in production since it has not gone through security audits or performance tests).

To start the dev server type in your console:

Our default base url is: http://localhost:8000/.
To get our admin interface: htp://localhost:8000/admin/

The login and password are the ones you entered for the database superuser.

We can’t see a menu to enter data for our application yet. We need to do something else first. We have to create restaurants/admin.py to add the models and fields we want to be able to edit through the admin site:

We have used the default interface for Food and Town and we have customized the Restaurant one. We could have used admin.site.register(Restaurant) but we have defined sections for the Restaurant model and we have ordered the fields.

This is the result of the Admin Site:

Admin Site

Admin Site

You can add all the data you need for a restaurant through the admin site now.

URLS and Views

Let’s design the public sites now. We need to define an url for each screen and a .html template linked to it along with a view if any data processing is needed.

We will define a specific URLconf module for the application under the restaurants folder that will be referred from the global URLconf module of the project. This application URLconf module maps urls with views (Python code) or templates (HTML). In case of a view it will call the corresponding HTML template.

Template Diagram

Template Diagram

By default Django looks by default for a subfolder called templates under the application root folder. In order to avoid conflicts between templates of different applications sharing the same project that may have the same name, is a good practise to add a subfolder under templates named as the application. As a result we will place our templates under restaurants/templates/restaurants/.

I have chosen rest_picker as the url for our application, getting a base url as http://localhost:8000/rest_picker/.

Let’s think in the workflow to define urls and parameters that we need to pass from one screen to another through the url.

  1. Choose a food: index.html
  2. URL: http://localhost:8000/rest_picker/
    We need to pass the food id to the next screen in order to do a filter to only show cities that have restaurants with that food.

  3. Choose a town: choose_town.html
  4. URL: http://localhost:8000/rest_picker/food/<food_id>
    For the next screen we need to pass the food id and the town id to display only restaurants for that town and with that food.

  5. Choose a restaurant: choose_restaurant.html
  6. URL: http://localhost:8000/rest_picker/food/<food_id>/town/<town_id>
    We only need to pass the restaurant id to the next screen.

  7. Restaurant details: rest_detail.html
  8. URL: http://localhost:8000/rest_picker/rest/<rest_id>
    Final screen.

rest_picker/urls.py

We are saying that all the urls that are like http://localhost:8000/rest_picker/ must look into the restaurants/urls.py file. The namespace parameter, again, is to avoid naming conflicts for different applications in the same project.

restaurants/urls.py

There are generic views to allow you write common views of data without having to write too much code. ListView is one of them. When the regular expression is met (http://localhost:8000/rest_picker/) it calls the template defined in template_name (index.html). It looks for it at the folder templates, since we created the restaurants subfolder under it we need to specify the relative path. It passes a list with all the objects of the Food model (food_list = _list) to the template. You can use a different name for this list of objects using the context_object_name attribute. Also, if you want to define a subset of objects you can use the queryset attribute along with a filter, for example something like queryset = Food.objects.filter(name_startswith=’H').

The name attribute we have defined for all urls lets you refer to it unambiguously from elsewhere in Django so you don’t have two urls with the same name. Again it is to avoid a naming conflict.

The rest of urls call to a function defined in views.py since they need of some Python code before calling the HTML template. You can see that the first parameter in the patterns function is not empty this time, it is set as restaurants.views. Because of this when you define the function to be called when the regular expression is met you only use choose_town. If the prefix would have been empty you would have had to use restaurants.views.choose_town.

Let’s look at (?P<food_id>\d+). Using parentheses around a pattern captures the text matched by that pattern and sends it as an argument to the view function; ?P<food_id> defines the name that will be used to identify the matched pattern; and \d+ is a regular expression to match a sequence of digits (i.e., a number). So, if we have http://localhost:8000/rest_picker/food/3 we will be calling to the function choose_town inside views.py and passing to it food_id=3.

The last part is used to serve the images uploaded through the admin site. This way of serving static files is ONLY valid when working with the development server where we can use the django.views.static.serve view. For production you will need to set up your web server to serve static files. This is out of the scope of this tutorial, you can find more information about this in the django site.

restaurants/views.py

The render function calls the HTML template and it passes the parameters needed in a dictionary to that template. Those parameters are processed in the Python code.

choose_town builds a list with the towns that have restaurants with that food_id and also the number of restaurants in that town with that food. This number is the one displayed in the bubble. We also transfer the food_id because we will need it later in the workflow.

choose_restaurant gets the restaurants with that food_id and town_id.

restaurant processes the field menu of the Restaurant model. We said before that we had to separate the elements in the list with semicolons when entering through the admin site. We are getting now this elements and passing them to the html template. The message parameter is empty by default.

vote is the function that processes the votation. It calls again to the restaurant html template but passing a Thank you message for voting. As this is a Model-View-Controller framework, the calculation of the votes should be contained in the models.py file and not in the views.py file to keep the independence of the parts. We have done it this way for simplication.

HTML templates

Now we will use the templates generated in the jQuery Mobile tutorial. We have to copy the .html files (index.html, choose_town.html, choose_restaurant.html, restaurant.html) under restaurants/templates/restaurants/.

The .css files are static files. Django looks for these files in a static folder placed under the root app folder. We need to create that directory (restaurants/static/restaurants/). In order to reuse the paths we used in the .html files of the jQuery Mobile tutorial we will create an images and a js folder under it and we will copy here all the resources. Let’s have a look how does the folder structure looks like now:

Let’s look at the templates now. We need to change some things to retrieve the data from our database.

index.html

I have highlightened the lines that have been changed adding Django syntax.

The first thing we have to do is to change the way of defining static files (.css, .js, .png). We specify that the element is static so that Django knows where to look for those resources, and then the relative path and the name to the resource.

We use the list of Food objects that we passed in the ListView (food_list) to go through all the foods. We display the name and the image associated to that food and also the url that must be called when clicking in one element passing the food_id.

The only thing that is going to change from one template to another is the body, so I will just copy the body for the rest of templates.

choose_town.html

We do the same here but going through the list of towns. This time we pass two parameters to the url linked to the town, the food_id and the town_id. And besides the name of the town we display the number of restaurants in that town for that food.

choose_restaurant.html

For the list of restaurants we display the image of the restaurant, the name and the starts. And we pass the restaurant_id to the template that will be called when clicking in a restaurant.

restaurant.html

For the restaurant.html template we must replace all the fix elements for dynamic oness. We use {{restaurant.name}}, {{restaurant.desc}}, {{restaurant.web}}, … I have also added the display of a message in the line 9. This message is the Thank you message that will only be displayed after a votation. The votation is submitted when we change the selection of the drop-down(onchange=”this.form.submit()”), for this reason we have to add the option “Choose your vote“. When submitted, it calls the vote view that we saw before that will do the calculations of the votes, storing the new value in the database and displaying the restaurant page with the Thank you message.

Because we have added another option to the drop-down list we need to adjust the .css file.

custom.css

We have completed the back-end of our application. You can find the code in github. Remember that you need to change the paths in the settings.py file to your own paths. You can ignore the requirements.txt file that is part of Python virtualenv and the migrations folder that is part of South since they have not been covered in this tutorial. Also it is very important that you include tests for your application. This is as important as the application code and it makes a difference in your application.

I hope you have found this tutorial useful!

4 comments

  1. July 17, 2013 at 5:24 pm David

    Great! i will try it!

  2. September 5, 2013 at 7:48 pm steve

    Thank you just need to learn about django :) Taken me forever to learn wordpress. Would be a great wp plugin :)

  3. September 26, 2013 at 11:18 am reeha

    could u pls help me how to do this in android eclipse????

  4. October 4, 2013 at 10:55 am Subbu

    hi,,
    Great tutorial…. well explained about the basic concepts of django.
    Can you explain me like how we can integrate this one with the front… ?

    Thanks…

Leave a reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">