Edx on Debian Stretch

Edx on Debian Stretch

After you clone the Edx repo there you will find a (undocumented) list of packages required to install on Ubuntu:


These packages and others are required for Debian Stretch.  First, install these packages:

sudo apt-get install $(grep -vE "^\s*#" requirements/system/ubuntu/apt-packages.txt   | tr "\n" " ")

And then install these packages:

sudo apt-get install python-scipy python-numpy build-essential python-dev gfortran libfreetype6-dev libjpeg-dev libtiff5-dev zlib1g-dev libpng-dev  libxml2-dev libxslt-dev yui-compressor graphviz libgraphviz-dev graphviz-dev mysql-server libmysqlclient-dev libgeos-dev libreadline7 libreadline7-dev mongodb nodejs mysql-client virtualenvwrapper libgeos-ruby1.8 lynx-cur libxmlsec1-dev swig  libsqlclient-dev libxmlsec1

Like the photo? See a bigger version on Flickr.

Migrate Django 1.4 to 1.11

Migrate Django 1.4 to 1.11

I thought these rough notes might be useful to anyone migrating from Django 1.4 (and possibly 1.3) to Django 1.11.

Moving from South to Django Migrations

1. Update your settings files:

Remove ‘south’ from your INSTALLED_APPS

2. Remove migrations.

Remove all app/migrations files except for __initi__.py . Remove any *.py[c|o] files.

Make sure there’s no migrations specific code in your app/migrations/__init__.py files


3. Run new Migrations

python manage.py makemigrations;

python manage.py migrate;

Moving from Django 1.3/1.4 -> 1.11

This is a 1.3 app migrated to 1.4 and now is being migrated to 1.11.

Will probably need a new manage.py file. Create a dummy project and copy manage.py over your existing manage.py file or diff the two). Rename your settings directory to match the name of your project. In my case the project is portal, settings renamed to portal.

URLS files:

django.conf.urls.defaults is replaced by django.conf.urls

patterns() is gone, see:




django.views.generic.simple is gone, removed in 1.5.

Replace django.views.generic.simple.direct_to_template with TemplateView:

from django.views.generic import TemplateView


from django.shortcuts import RequestContext

Replaced with:

from django.template import RequestContext


django.contrib.databrowse is gone. See:


This error:

django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form BlahForm needs updating.

Change in Django 1.8. See:

Quick fix is:

fields = '__all__'

But you will need to confirm that you want the form to expose all fields.


Removal of django.contrib.formtools:

Is now separate package, install with pip:

pip install django-formtools

Change imports from django.contrib.formtools to formtools. For example:

from django.contrib.formtools.preview import FormPreview


from formtools.preview import FormPreview


model._meta.get_all_field_names() is gone.



This is verbatim from the docs:

MyModel._meta.get_all_field_names() becomes:

from itertools import chain
    (field.name, field.attname) if hasattr(field, 'attname') else (field.name,)
    for field in MyModel._meta.get_fields()
    # For complete backwards compatibility, you may want to exclude
    # GenericForeignKey from the results.
    if not (field.many_to_one and field.related_model is None)

This provides a 100% backwards compatible replacement, ensuring that both field names and attribute names ForeignKeys are included, but fields associated with GenericForeignKeys are not. A simpler version would be:

[f.name for f in MyModel._meta.get_fields()]

While this isn’t 100% backwards compatible, it may be sufficient in many situations.



BaseCommand.option_list is gone.

See https://docs.djangoproject.com/en/1.11/releases/1.8/#extending-management-command-arguments-through-command-option-list .


See here for how to add arguments:


These custom options can be added in the add_arguments() method like this:

class Command(BaseCommand):

    def add_arguments(self, parser):

        # Positional arguments

        parser.add_argument(‘poll_id’, nargs=‘+’, type=int)

        # Named (optional) arguments






            help=‘Delete poll instead of closing it’,


Move from MySQL to Postgres

Bigger or more complex databases may want to do a manual migration where the database is migration using django models.


I’ll update this as I have time.

Migrate Section of a Git Repo to a new Git Repo

I inherited a git repo that has multiple projects in it. It’s easier to manage the code and dependencies if each of these projects are in their own git repo.

The process is pretty simple:

  1. Export the directory you plan to use as the starting point of the new repo
  2. Create the new repo
  3. Import the old repo

  1. Export the directory
git log --pretty=email --patch-with-stat --reverse --full-index --binary DIRECTORY > /tmp/DIRECTORY_patch;

2. Create the new repo

git init REPONAME;

3. Import the old


git am < /tmp/DIRECTORY_patch;

Run ‘git log’ to verify that you’ve successfully import the repo.

Let’s Encrypt Cert & Nginx (Using a Web Proxy) on Centos 6.x

Let's Encrypt Cert & Nginx (Using a Web Proxy) on Centos 6.x

This was done on Centos 6 where prebuilt ‘certbot’ packages are not available. On Centos 7, install ‘certbot’ from the EPEL repo.

cd ~root;
mkdir certbot;
wget https://dl.eff.org/certbot-auto;
chmod 755 certbot-auto;

This installs packages, including gcc, which you may want to uninstall as it’s bad practice to have compilers on a external facing (public) Web server.

On my server I have a different configuration file for each server we’re proxying for. These are in /etc/nginx/conf.d/ and using a naming convention of:


For example, example.com would be:


Edit your config file and add this after location / { … } :

location /.well-known {
alias /tmp/static/.well-known;


mkdir /tmp/static/;

Run certbot:

./certbot-auto certonly

Continue reading Let’s Encrypt Cert & Nginx (Using a Web Proxy) on Centos 6.x

django.db.utils.DataError: invalid value for parameter “TimeZone”

If your Django Apps throws this error:

    cursor.execute(self.ops.set_time_zone_sql(), [tz])

django.db.utils.DataError: invalid value for parameter "TimeZone": "America/New_York"

The problem is that your Database and Django app are set to use different timezones.

Search your Django settings files for this:


And then connect to your database and query for the timezone. In Postgres run this query:

show timezone;

The fix is to have your Database and Django app use the same time zone. The quickest fix is to set TIME_ZONE in your Django app to be the same as your Database.

OnePlus One: No LTE or Network

I recently upgraded my OnePlus One to Android 6.0.1 and while I can make phone calls I don’t have any network connectivity unless I’m on WiFi. The symptoms are;

  • Can’t send email,
  • No access any websites
  • Phone is not on a LTE network

This awkward fix, posted byrohitvermamech on the OnePlus Forums  get’s LTE and networking working again:

Step 1:
Go into Settings > Mobile Networks > Access Point Names > Restore Defaults
The list should now have many many more choices of APNs. Choose the correct APN. Then go into Settings > Mobile Networks > Network Operators (make sure you are connected to WiFi) click “Choose Automatically”. Then turn Aeroplane Mode on and back off.
Step 2:
VERY IMPORTANT! Restart your phone.
Step 3:
Go into phone and dial *#*#4636#*#* and choose Phone Information. In Phone Information set the Preferred Network Type to LTE/GSM auto (PRL) [even if it says it already, do it again]. Turn off the radio. When the radio is turned off, turn the radio back on. Go down to the SMSC and hit “Refresh” and then “Update”.


My Phone Collection.

My Phone Collection.
My Phones over the years.
My Phones over the years.
Starting on the left is my very last feature phone a Sony Ericsson C902. Of all of these phones it makes the best phone-calls. Keeping this thing as it was such a great phone.
Still available for $120 at Amazon!
Next, Liz’s first Android phone — a Virgin Mobile LG Optimus V.  Keeping this as we can quickly reuse it for any visitors from Ireland and it’s a simple phone to use.
Next is my second Android phone a Samsung S2, I got this phone as the screen on my first Android a HTC Sensation cracked. I still have the HTC as I had plans to replace the screen but it’s hardly worth it at this point. The S2 was quite a step-up, lovely screen but it was missing a little something (this phone is being gifted to a friend for reuse), I hope he finds it better than today’s cheap Android phones.
Next up is my 3rd Android a Google Nexus 4, this was the first Android phone that really, really impressed me and is still a great device — fantastic camera too. I use this as my Irish Phone and it has my Irish SIM card in it and I’ll be walking around Ireland later this week with two phones as my US T-Mobile plan gives me free texts and data while in Ireland, and I can make free phone calls to any Irish phone after topping this up with 20 Euros.
The big yoke is my current phone a OnePlus One, fabulous device almost too big but at least I can read the text on the screen! 😉
Next a sweet Amazon Fire Phone that is someone’s Christmas present. Hopefully the Amazon App Store won’t be a dealbreaker …

404 Errors On Pagespeed Generated JS & CSS

To improve performance of the SBGrid Web site I’ve been using Google’s Pagespeed Module for Apache. There is a module available for both Apache & NGinx, and  it can improve the performance of a Web site using a number of methods such as minimizing the number of JavaScript and CSS files that need to be downloaded.

We were seeing random 404 errors on Google Pagespeed auto-generated JavaScript and CSS files on the SBGrid’s Web site. These would only occur after the Web server was running for 2 days or more.

The fix for us was to increase Pagespeed’s caches and to give the host (it’s a VM) more RAM.

These are the values that we set:

  • ModPagespeedFileCacheSizeKb
    • Set the target size (in kilobytes) for file cache.
  • ModPagespeedLRUCacheKbPerProcess
    • Set the total size, in KB, of the per-process in-memory LRU cache.
  • ModPagespeedLRUCacheByteLimit
    • Set the maximum byte size entry to store in the per-process in-memory LRU cache.

This is what we set them to:

ModPagespeedFileCacheSizeKb 102400
ModPagespeedLRUCacheKbPerProcess 1024
ModPagespeedLRUCacheByteLimit 16384

Use these with care and make sure that your host has enough RAM to fit everything into memory without paging.

Original Image from my Flickr Feed.



Linux, Python, Boston, Donegal.