Using Django and MongoDB to Build a Blog

4) Add the name of the LJblog app to the list of the INSTALLED_APPS in the LJ/settings.py file. If you do not install the app, you will not be able to use it. So, the INSTALLED_APPS variable should have the following values:


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'LJblog',
    'django_extensions',
)

As you can see here, it also is required to install a package called django-extensions. If your Linux distribution does not provide a ready-to-install package, visit the Django Extensions site for instructions about installing it.

4) Many other changes had to be made in the LJ/settings.py file. The following diff output shows the changes:


$ diff settings.py{,.orig}
3,5d2
< import os
< PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
< 
14a12,23
> DATABASES = {
>   'default': {
>       'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 
                                         # 'mysql', 'sqlite3' or 
                                         # 'oracle'.
>       'NAME': '',      # Or path to database file if using sqlite3.
>       # The following settings are not used with sqlite3:
>       'USER': '',
>       'PASSWORD': '',
>       'HOST': '',      # Empty for localhost through domain sockets 
                         # or '127.0.0.1' for localhost through TCP.
>       'PORT': '',      # Set to empty string for default.
>   }
> }
> 
44c53
< MEDIA_ROOT = os.path.join(PROJECT_ROOT, '..', 'media')
---
> MEDIA_ROOT = ''
49c58
< MEDIA_URL = '/media/'
---
> MEDIA_URL = ''
55c64
< STATIC_ROOT = os.path.join(PROJECT_ROOT, '..', 'static')
---
> STATIC_ROOT = ''
63d71
< 	os.path.join(PROJECT_ROOT, 'static'),
103d110
< 	os.path.join(PROJECT_ROOT, 'templates'),
148,159d154
< 
< AUTHENTICATION_BACKENDS = (
<     'mongoengine.django.auth.MongoEngineBackend',
< )
< 
< SESSION_ENGINE = 'mongoengine.django.sessions'
< 
< MONGO_DATABASE_NAME = 'LJ_blog'
< 
< from mongoengine import connect
< connect(MONGO_DATABASE_NAME)
< 

Note: the name of the MongoDB database is defined and stored in the MONGO_DATABASE_NAME variable.

5) The contents of the LJ/urls.py file should be the following:


from django.conf.urls import patterns, include, url
from django.conf import settings
from LJblog.views import PostListView

urlpatterns = patterns('',
	url(r'^$', PostListView.as_view(), name='list'),
    url(r'^post/', include('LJblog.urls'))
)

6) Inside the LJ/LJ directory, you need to create two directories, called static and templates, and copy some files and directories inside them. The project uses the Twitter Bootstrap set of tools for creating Web sites and Web applications.

The following output shows the full contents of the static directory:


$ ls -lR static/
total 0
drwxr-xr-x@ 6 mtsouk  staff  204 Sep 21 14:13 bootstrap

static//bootstrap:
total 0
drwxr-xr-x@ 6 mtsouk  staff  204 Jan  5  2013 css
drwxr-xr-x@ 4 mtsouk  staff  136 Jan  5  2013 img
drwxr-xr-x@ 4 mtsouk  staff  136 Jan  5  2013 js

static//bootstrap/css:
total 544
-rwxr-xr-x@ 1 mtsouk  staff   21751 Jan  5  2013 
 ↪bootstrap-responsive.css
-rwxr-xr-x@ 1 mtsouk  staff   16553 Jan  5  2013 
 ↪bootstrap-responsive.min.css
-rwxr-xr-x@ 1 mtsouk  staff  124223 Jan  5  2013 
 ↪bootstrap.css
-rwxr-xr-x@ 1 mtsouk  staff  103314 Jan  5  2013 
 ↪bootstrap.min.css

static//bootstrap/img:
total 56
-rwxr-xr-x@ 1 mtsouk  staff   8777 Jan  5  2013 
 ↪glyphicons-halflings-white.png
-rwxr-xr-x@ 1 mtsouk  staff  12799 Jan  5  2013 
 ↪glyphicons-halflings.png

static//bootstrap/js:
total 184
-rwxr-xr-x@ 1 mtsouk  staff  58516 Jan  5  2013 
 ↪bootstrap.js
-rwxr-xr-x@ 1 mtsouk  staff  31596 Jan  5  2013 
 ↪bootstrap.min.js

The templates directory contains two files, as the output of the ls -lR command shows:


$ ls -lR templates/
total 16
-rwxr-xr-x@ 1 mtsouk  staff  1389 Sep 25 21:25 base.html
-rwxr-xr-x@ 1 mtsouk  staff   148 Jan  5  2013 messages.html

The base.html file contains project-specific information that you can change.

7) The connection to the MongoDB database happens inside the LJ/settings.py file. Django needs the following two commands to connect to a MongoDB database:


from mongoengine import connect
connect(MONGO_DATABASE_NAME)

8) Next, you should create four HTML files inside the templates/LJblog directory. They are the displayed Web pages for the Create, Read, Update and Delete operations:

  • create.html

  • detail.html

  • list.html

  • update.html

The selected filenames must match the parameters found inside the LJblog/urls.py file.

9) The contents of the LJblog/urls.py file are the following:


from django.conf.urls import patterns, url
from views import PostCreateView, PostDetailView, 
 ↪PostUpdateView, PostDeleteView

urlpatterns = patterns('',
    url(r'^add/$', PostCreateView.as_view(), name='create'),
    url(r'^(?P<pk>[\w\d]+)/$', PostDetailView.as_view(), 
    ↪name='detail'),
    url(r'^(?P<pk>[\w\d]+)/edit/$', PostUpdateView.as_view(), 
    ↪name='update'),
    url(r'^(?P<pk>[\w\d]+)/delete/$', PostDeleteView.as_view(), 
    ↪name='delete'),
)

10) Next, you need to edit the models.py file. This file is where data models are defined.

Using Django's ORM (Object-Relational Mapper) is one of the project's goals. ORM allows the Python classes that were defined inside models.py to access the selected database without requiring you to deal with the database directly. ORM is a major advantage of Django.

The Post Python class is defined as follows:


class Post(Document):
    user = ReferenceField(User, reverse_delete_rule=CASCADE)
    title = StringField(max_length=200, required=True)
    text = StringField(required=True)
    text_length = IntField()
    date_modified = DateTimeField(default=datetime.now)
    is_published = BooleanField()

As you will see later in this article, the Post MongoDB table has a direct connection to the Post Python class.

11) Then, you need to edit the forms.py file. The forms.py file allows Django to access user-submitted form data.

12) Last but not least, you should edit the views.py file. This file includes the functions that handle data as well as various other things.

The directory structure of the project as well as the included files are shown in Figure 3. You also will notice files ending with .pyc. These are byte-code files created by the Python interpreter that are executed by the Python virtual machine.

Figure 3. The Directory Structure of the Django Project

______________________

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix