If you read the doc­u­ment­a­tion closely enough, of course all the inform­a­tion is there. Get­ting the order of oper­a­tions right, how­ever, can cause the odd issue.

Devel­op­ing Django apps means apply­ing migra­tions, and those don’t always do what’s expec­ted. In that case, you can roll back to the n-1 migra­tion by using ./manage.py migrate [app_label] {n-1_migration_label}, then delete the nth migra­tion, then edit the models.py to try again.

To clean up the data­base from some third-party app you decide you don’t want after all, you use ./manage.py migrate [app_label] zero to get rid of the migra­tions from that app. You have to run this before delet­ing the app from your settings.py file.

One of my cli­ent web­sites sud­denly star­ted giv­ing an error: Error estab­lish­ing a data­base con­nec­tion. When I went to the /wp-admin URL, the error was still there.

This par­tic­u­lar web­site is on shared host­ing, so I logged into the CPanel and checked the data­base was still there. Then I checked the data­base and found some issues with some of the tables.

[site.wp_links] error: Table upgrade required. Please do "REPAIR TABLE wp_links" or dump/reload to fix it!
[site.wp_options] error: Table upgrade required. Please do "REPAIR TABLE wp_options" or dump/reload to fix it!
[site.wp_postmeta] status: OK
[site.wp_posts] status: OK
[site.wp_term_relationships] status: OK
[site.wp_term_taxonomy] error: Table upgrade required. Please do "REPAIR TABLE wp_term_taxonomy" or dump/reload to fix it!
[site.wp_terms] status: OK
[site.wp_usermeta] error: Table upgrade required. Please do "REPAIR TABLE wp_usermeta" or dump/reload to fix it!
[site.wp_users] error: Table upgrade required. Please do "REPAIR TABLE wp_users" or dump/reload to fix it!


Run­ning those SQL quer­ies on the appro­pri­ate data­base in phpMy­Ad­min fixed the prob­lem. I don’t know whether the host­ing com­pany upgraded the data­base, or some­thing happened with the auto­matic Word­Press upgrade sys­tem, or if some­thing else caused the prob­lem.

[Update] There were a bunch of other errors that cropped up after­wards with the White Screen of Death; I had to call the host­ing com­pany to sort out the server-side errors caus­ing those. It’s pos­sible those errors were the ori­ginal cause of the data­base prob­lems, whatever they were.

I dis­covered another issue while deploy­ing to Python­Any­where (maybe it’s applic­able to other PAAS pro­viders as well).

There was an odd Impor­t­Er­ror when run­ning manage.py. In the spe­cific case I had, it showed up when run­ning the tests with coverage: from Uni­path import Path Impor­t­Er­ror: No mod­ule named ‘Uni­path’. It turned out I hadn’t installed cov­er­age in the vir­tual envir­on­ment, which meant the sys­tem was using the default one. Installing cov­er­age in the vir­tual envir­on­ment as well fixed the prob­lem.

A check­list for mov­ing a Django-Wagtail pro­ject to Python­Any­where. There is doc­u­ment­a­tion on the Python­Any­where site; mine includes things I for­get.

Setup: devel­op­ment and test­ing on my laptop, sta­ging and pro­duc­tion on Python­Any­where.

The help files are pretty good, but I need my own check­list. Right now I’m in the sta­ging mode, but at some stage I’ll be mov­ing to pro­duc­tion. No point fig­ur­ing out the same things twice!

1. Develop on laptop in a vir­tualenv. Push com­mits reg­u­larly to bit­bucket account. At some stage squash the migra­tions and clean those up. Four sets of set­tings: dev, test­ing, sta­ging, pro­duc­tion.
2. Set up account on Python­Any­where that allows the use of Post­gres (it’s an add-on to a cus­tom plan).
3. Cre­ate vir­tualenv and set up sta­ging web app. Delete vir­tualenv when you real­ise you didn’t use the right ver­sion of Python and the default is 2.7, not 3.5. Recre­ate the vir­tualenv with python 3.5.
4. Clone the repos­it­ory (using the ssh-keygen instruc­tions). Redir­ect the pub­lic key to a file so you can copy it without line-breaks get­ting in the way.
5. pip install -r requirements/production.txt (includ­ing psycopg2, which I didn’t need for devel­op­ment).
6. Cre­ate the Post­gres server, user, and data­base Don’t for­get a strong pass­word for the user (owner of the pro­ject data­base).
7. Update the set­tings file with the data­base set­tings.
8. Set the envir­on­ment vari­ables for the set­tings and the secret key (gen­er­ator).
9. Attempt to apply the migra­tions. This will show where you made mis­takes on all the pre­ced­ing steps.
10. Fix the mis­takes. Reload the web app to see if any­thing shows up.
11. Set up the static file server. Check the static files are being served cor­rectly.
12. Cre­ate the Django super­user and log in.

The next step is data, of course.

Over the Christ­mas break I made a couple of dips, one of which got bet­ter reviews than the oth­ers. This is not a recipe for pur­ists, since a real tapen­ade should have anchovies in it, but I didn’t have any and my fam­ily doesn’t like them any­way.

None of the quant­it­ies are exact. The sun-dried toma­toes were loosely packed in the meas­ur­ing cup and I didn’t meas­ure the olives, just drained the can and tossed them in the food pro­cessor. I didn’t chop any­thing before put­ting it in the food pro­cessor.

• Approx 2 cups black olives (con­tents of one can, 398ml size). I used Cali­for­nian black olives since those were in the cup­board, next time I’ll prob­ably use Kala­mata olives.
• Approx 3/4 cup oil-packed sun-dried toma­toes; let most of the oil drip off but not all of it.
• 5 cloves of gar­lic.
• 2 tbsp capers

Pro­cess in a food pro­cessor until finely chopped. If it’s too dry, add a few drops of olive oil (or oil from the sun-dried toma­toes).

Word­Press was designed for pub­lic web­sites, not private ones, so pass­word pro­tec­tion can be a little clunky. For­tu­nately there are plu­gins to help, but (as always) there are trade-offs to be made.

When all you want to do is add a pass­word to stop search engines index­ing and out­siders read­ing the con­tent, but you also want make it as easy as pos­sible for people to use, there’s the Pass­word Pro­tec­ted plu­gin. As it says, it doesn’t pro­tect the images or other uploaded con­tent.

If you also want to pro­tect the media, you will need to give people an account on the Word­Press site (with user­name and pass­word). Then you can use the htac­cess edits detailed at http://www.idowebdesign.ca/wordpress/password-protect-wordpress-attachments/. This works, but in many cases you just don’t want to give lots of people accounts on the sys­tem, or make groups of people share an account. So it’s a trade-off — how import­ant is password-protecting the images versus the admin­is­tra­tion over­head of user accounts with the asso­ci­ated username/password ease of use issues? If you do want to use user­names and pass­words, per­haps giv­ing a group of people a shared account, I’d recom­mend also using one of the plu­gins that helps with finer-grained access con­trol, such as Mem­bers, to stop people being able to change things you don’t want them chan­ging (such as pass­words for the shared account).