# django – some first impressions

Since I mastered the setup of my apache config to actually find my django project I experience some more fluent development happening.

Actually I learned already a lot about the powerful namespacing pattern for URLs which frees up a lot of capacity you usually spend on fixing broken link experiences for users and wrapping your head around url-paths.

Actually the url-handling via regex is a bit painful at first, but it turns out that this gives you extraordinary flexibility to create wonderfully simple and elegant looking urls which is a thing nowadays if you wanna be found in Google at the top ranks and provide useful permalinks e.g. for products whoich should be found easily.

Also the template engine is very flexible. I can create a kind of loopholes (called blocks) in my base templates to prepare them to get stuff injected from lower level templates which is great. You could build a very complex site in no time and have things like header, navigation, content, footer easily setup and look consistently.

### Learning with the best tutorials

After I did the painful 6-part tutorial, I just did another very good tutorial on youtube (and still executing on it). And boy was I happy to actually have learned things the „right way“ before. because in the youtube based tutorial above the guy explaining stuff there totally misses on the concept of url-namespacing. But see for yourself here:  


  
  
**Source:** Django Full Website Tutorial by hackedexistence.com

**If you know some excellent tutorials** , e.g. on how to setup django for SSL-based deployment and the like, **let me know** in the comments.

I also found **some very helpful other links** :

  * Django Tutorial Part 1 of 13 on Youtube
  * Class Based Views Inspector to create a MUCH better documentation from djangos classes
  * Nice Django 1.5 documentation
  * Python Imaging Library which is needed to handle images
  * Another great tutorial (video) by **Michael Herman** who also documented the tutorial materials on realdjango.herokuapp.com



### Python tricks often appreciated

During all my tinkering I also did used a lot of really useful operations using the `manage.py` command. E.g. today I just wiped my database to try repopulating it with stuff I dumped before. It was quite easy and which is good to have for experimenting and not loosing all your data. Just **be careful** you do not change the DB-scheme during these operations.

`  
python manage.py dumpdata  > temp_data.json  
python manage.py flush   
python manage.py loaddata temp_data.json  
`

I also made a lot of use of following command:  
`  
python manage.py shell  
`  
This loads the whole project or in a way has all the settings needed setup for you. Some quick  
`  
>>> from <myApp>.models import <myEntity>  
>>> dir(<myEntity>)  
`  
Gave me really helpful insights, what the object I have actually is capable of doing, by displaying all the methods and attributes available.

My bootstrapping file for Vagrant now was extended by a lot of useful stuff, but actually I did not destroy my VM recently so if all this works will be seen on the next setup of my VM using `vagrant up`.

Content I added to my **bootstrap.sh** file:  
`  
# SETUP FOR BOOTSTRAPPING  
apt-get update`

# INSTALL apache  
apt-get install -y apache2

# INSTALL mod_wsgi  
apt-get install libapache2-mod-wsgi

# INSTALL django  
apt-get install -y python-django

# INSTALL python imaging library  
apt-get install python-imaging python-imaging-tk

# INSTALL postgres & python db connector  
apt-get install postgresql python-psycopg2  


I also backed up my apache config files now to some place external to the VM (shared folder) so I do not loose all config stuff if I destroy the VM.

### Further education

To gain some flexibility for my models I just started reading stuff like e.g. „33 projects that make developing django apps awesome“ and „Django database migration tool: south, explained“.

**South** (start Tutorial here) looks like an elegant solution for my purposes because it provides intelligent schema and data migrations.

The plain vanilla way to do migrations would be Django’s Evolution. But even they point out that South has become a **De facto standard**. Looks like some stuff was inspired by ActiveRecord from rails.

So some line of  
`sudo apt-get install python-django-south`  
just made it fly. I like the ubuntu way of installing software… just to revert the action using  
`sudo apt-get remove --purge python-django-south`  
several minutes later because south was not correctly installed and better should have been installed through using pip.

So doing a `sudo pip install south` to get the e x a c t same result. So must be some other error. Doing some googleing on that one… turns out south needs to be entered in the INSTALLED_APPS entry in the settings.py… nice that you find that on the documentation so easily. So this stackoverflow-line helped me out again:

> You probably haven’t added ’south‘ into the list of INSTALLED_APPS of your settings.py file

But at least I now know the exact version of south installed. It’s 0.8.2 the one installed by **apt-get** was only 0.7.3, so I guess pip is the better way to fly. And now python manage.py did show:  
`  
[south]  
convert_to_south  
datamigration  
graphmigrations  
migrate  
migrationcheck  
schemamigration  
startmigration  
syncdb  
test  
testserver  
`

**Fine!** Now that I got that installed the `python manage.py syncdb` changed its output to some new formatting which involves some south-magic. It now looks like:  
`  
Syncing...  
Creating tables ...  
Creating table south_migrationhistory  
Installing custom SQL ...  
Installing indexes ...  
Installed 0 object(s) from 0 fixture(s)`

Synced:  
> django.contrib.auth  
> django.contrib.contenttypes  
> django.contrib.sessions  
> django.contrib.sites  
> django.contrib.messages  
> django.contrib.staticfiles  
> django.contrib.admin  
> south  
> shop  
> shopadmin  
> tinymce

Not synced (use migrations):  
-  
(use ./manage.py migrate to migrate these)  


I just coninued to put my models under migration control using:  
`python manage.py schemamigration <myapp> --initial`  
**Worked!** But everything after that failed. Even a **flush** on the database did not help in any way. Hmm…  
Adding south to an existing project needs special handling…  
`python manage.py convert_to_south <myApp>`  
also learned that deleting the migrations directory is not that evil after all if **„things go south“** , haha.

### Migrations on the server

At the same time I learned that there is a procedure for handling migrations perfectly on the server, its like this:

  1. Install South on server. import south from shell just to make sure you are using the same python env. 
  2. Add ’south‘ to INSTALLED_APPS in settings.py
  3. Upload settings.py
  4. Restart (web)server
  5. `python manage.py syncdb`
  6. Upload new app/models.py and app/migrations/ dir
  7. Restart (web)server
  8. `python manage.py migrate app --fake 0001`
  9. `python manage.py migrate app`



**Good to know!** Since I got some changes to my models waiting, I changed them now and handed over to south:  
`  
python manage.py schemamigration myproject.myapp --auto  
python manage.py migrate myproject.myapp  
`  
Worked like a charme… after fixing some modelissues (adding null=True) and providing default values for some Decimals. Great!

Oh and if you have permission problems with your webserver directory in your VM managed by Vagrant, try adding following line in the **Vagrantfile** :  
`config.vm.synced_folder "./", "/vagrant", :owner=> 'vagrant', :group=> 'www-data', :mount_options => ['dmode=775', 'fmode=775']`  
This adds the directory to the group of the apache-users, so apache is allowed to write into those files. Here it is `www-data`-group but it may be different for your VM/Webserver combination.

### Localization

Today I tried to use translated strings in my templates e.g. using following statement in one template  
`{% trans 'Willkommen auf meiner Homepage.' %}`  
you need to add  
`{% load i18n %}` at the top of each template file and below any base-template statements.  
using `django-admin.py makemessages -l de --all`  
I tried to create localizationfiles for my app. But that did not really work because I needed to create `locale`-dirs first in my project.  
And then I got the famous error:  
CommandError: Error running xgettext. Note that Django internationalization requires GNU gettext 0.15 or newer.  
which I fixed using the ubuntu SW installation manager by typing  
`sudo apt-get install gettext`  
and adding it to the **bootstrap.sh** for my VM.

Then after entering  
`django-admin.py makemessages -l de --all`  
which created a **.po-file** in my project  
`locale/de/LC_MESSAGES/django.po`  
Repeating the same procedure for english language revealed another folder for en. But…  
that alone was not sufficient by far. You need to do a **compile** on the locale files before you even have a chance of seeing translation happen.  
`django-admin.py compilemessages` and in my case  
I also needed to add the LOCALE_PATHS to actually find my locale dir in the project, i have no clue why it does not find that automatically as advertised.

### Authentication and sending mails

In the meantime I implemented registration/login/logout and user profile. Following my tutorials I just took django’s default implementation of how to reset passwords for user accounts. That’s when I hit the next wall. But that was really an easy one. If you want to send mails you need a mailserver. After some googeling i went with postfix for testing:  
`sudo apt-get install postfix`  
made this work, otherwise I saw an error which pointed me directly towards the problem. I need to remember this for deployment to actually install a maiserver which is stable and configure it in the **settings.py** according to this and this and during development maybe this.

Actually I would prefer to just setup the following settings:  
`  
EMAIL_HOST = 'localhost'  
EMAIL_PORT = 1025  
`

and then type  
`python -m smtpd -n -c DebuggingServer localhost:1025`  
this prints emails which are normally sent via any configured mailserver to the console to debug its content and headers. Very useful!!!

Other useful stuff I discovered during my voyage… (basically I just store all the open tabs on my browser here, because I need to reboot the machine for some hardware driver I need to install which needs a reboot of my mac.)

  * Some criticism of the ClassBasedView-model
  * Date/time formatting symbols for strftime-lib
  * Python v3.3.2 documentation (future)
  * Deploy Django (kind of a book)
  * How to use Django with Apache and mod_wsgi 
  * List of python IDE’s
  * Standard String Formatters for python data types
  * PyPI – the Python Package Index
  * The Advanced Tutorial I should start on next…
  * Class-based views API reference
  * How to query for objects in django
  * ‚RealPython‘ which looks like… mmmmmh ‚dnt know… 



Wow, the new device driver fixed my issue with this gaming mouse. The default behaviour of the **Cyborg R.A.T. 9** mouse is really pretty ugly. Have a look at this enormous proof of how MadCatz actually doesn’t even care about any Mac customer. Actually you should not buy anything from a company which behaves silly as this. It renders your mousepointer nearly useless. Since Cyborg did never provide any fix for the missing OS X driver and installing the old driver for OS X 10.6 renders completely crazy issues with the mouse… I went with **USB Overdrive** now. And wow it seems to fix the issues. I cannot manipulate the 3 different setups of the mouse, but I can pretty much freely configure any other button and all scrollwheels now. Great thanks to USB Overdrive! **BTW:**here is a great review of USB Overdrive.

### Taking a REST

Today I started opening up my small website using some **REST API**. I started installing necessary stuff following instructions over here by typing:  
`  
sudo pip install djangorestframework  
sudo pip install markdown  
sudo pip install django-filter  
`

**Wow!!!! Blown away just another time! REST-API support in actually no time. Haha, how cool is that?**

By working my way through the tutorial on how to JSONify stuff, I created my own `apiviews.py` (I did not want that API stuff in my regular views) and then I just setup the urls.py with som additional info. (meanwhile I found myself trying to close a browser tab by typing `:q` in the window, perhaps it is time for vimperator…). I used the python interactive shell to actually experiment with the stuff in the tutorial. Which is really perfect to get to know the details of how JSONParser and JSONRenderer actually work, i.e. using a stream created with StringIO.

So in the end this took me just one day to grab the concept of JSON-api-ifying my django app to get at least a stable READ-ONLY api. But now I will go on and work on the READ,CREATE,WRITE,DELETE stuff which will involve some validations of incoming JSON and objects created. We will see…

**BTW:** Meanwhile I just found another nice Video Tutorial on the Python/Django stuff. Looks also very clear in its explanations and also provides some much better input about the background of how django works. So definitely worth a try, though the guy smartly „skips“ (edited out of the video) several very delicate things (like installing the mySQL amd mysql-python, haha).

**Update**  
To make my own experience on video-tutorials as comfortable as possible I just hacked myself a website for one of the tutorial series. It allows to insert any video-id from youtube and will allow free resizing of the video display. Also I preprogrammed the HackedExistence ID’s for you already. So convenience is just 1 click away.

_To be continued…_