expoweb/handbook/troggle/trogdjangup.html

201 lines
13 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Handbook Troggle and Django</title>
<link rel="stylesheet" type="text/css" href="../../css/main2.css" />
</head>
<body><style>body { background: #fff url(/images/style/bg-system.png) repeat-x 0 0 }</style>
<h2 id="tophead">CUCC Expedition Handbook</h2>
<h1>Upgrading Django for Troggle</h1>
<h4>Why this is difficult</h4>
<p>When django upgrades to a new version things break across the entire django package, including things which we don't conciously use but are internal dependencies within django. These were 'the way to do it' when troggle was first written for django 0.7 in 2006. So upgrading troggle to a new django version requires not just a broad beadth of knowledge across troggle, but also across the entire breadth of django itself. And the error messages are sometimes very unhelpful.
<h4>Django versions and update schedule</h4>
<div align="center">
<a href="https://www.djangoproject.com/download#supported-versions">
<img border="1" width="65%" src='release-roadmap.3c7ece4f31b3.png'/></a></a>
<table style="border:1px solid black; background-color: #C9F0DD;" >
<tr>
<th>Release Series</th>
<th>Latest Release</th>
<th>End of support</th>
<th>End of security fixes</th>
</tr>
<tr>
<td>3.2 LTS</td>
<td>April 2021</td>
<td>December 2021</td>
<td>April 2024</td>
</tr>
<tr>
<td>3.1</td>
<td>3.1.7</td>
<td>April 2021</td>
<td>December 2021</td>
</tr>
<tr>
<td>3.0</td>
<td>3.0.13</td>
<td>August 2020</td>
<td>April 2021</td>
</tr>
<tr>
<td>2.2 LTS</td>
<td>2.2.20</td>
<td>December 2019</td>
<td>April 2022</td>
</tr>
<tr class="unsupported">
<td>1.11 LTS <sup></td>
<td>1.11.29</td>
<td>December 2017</td>
<td>April 2020</td>
</tr>
</table>
</div>
<h4>Major, minor and releases</h4>
<p>Django release 2.2.20 is major-version 2, minor-version 2, and patch-release 20. 2.2 is the "feature release" and patch releases within each feature release are not meant to break anything. They are just to fix bugs.
<p>Things <em>will break</em> between <a href="https://docs.djangoproject.com/en/dev/internals/release-process/">feature releases</a> which come out every 8 months.
<p>You will come to rely extensively on <a href="https://docs.djangoproject.com/en/3.2/releases/">the release notes and versions documentation</a> which is maintained by django.
<p>You will also need to read the django <a href="https://docs.djangoproject.com/en/3.2/howto/upgrade-version/">guide to upgrading to newer versions</a>.
<h4>Django plugins ("apps")</h4>
<p>Documentation for the plugins is highly variable and plugin projects, being run by volunteers, can just die unexpectedly. For the django-registration plugin there are two sources of current information:<br />
<a href="https://django-registration.readthedocs.io/en/3.1/">Docs: django-registration 3.1</a><br />
<a href="https://pypi.org/project/django-registration/">PyPi: django-registration 3.1</a><br />
<p>but only one of these (PyPi) gives release history data - which is what you need if you get behind with the django upgrades.
<p>Django plugin documentation cannot be relied upon to tell you which version of django they require. They will complain when you run them if your version of django is too old though. Some experimentation is required.
<p>[ However django-extensions looks like it could be useful explicitly to help us through the upgrade process:
<a href="https://pypi.org/project/django-extensions/">pypi.org/project/django-extensions/</a> (only available for django 2.2 and later). ]
<h3 id="djangotricks">Important Tricks</h3>
<p>There are six critical tricks that make everything much, much easier:
<ol>
<li>Use <a href="https://docs.python.org/3/library/venv.html">pip venv</a> or virtualenv to set up a virtual python environment within which you can easily and quickly change the specific releases of python, django, django's dependencies and django plugins.
With a previously created venv <var>py37d2</var> start it up like this:<br />
<var>cd py37d22<br />
source bin/activate<br />
python --version<br />
cd troggle<br />
django-admin<br />
python manage.py<br />
python manage.py validate -v 3 --traceback<br />
django-admin check <br />
python manage.py test -v 3 --traceback</var>
<li>Use the <em>highest release number</em> when upgrading between minor-versions of django. <br />So we went from 1.8.19 to 1.9.13 to 1.10.8 to 1.11.29 to 2.0.13 to 2.1.15 then 2.2.19 (.20 was not released then) and next we will go to 3.2.x .
<li>Use the django 'check' maintenance system at the most verbose setting at each release<br />
<var>troggle$ python manage.py check -v 3 --deploy</var><br>
<var>troggle$ python -Wall manage.py check</var><br>
<li>Use our test suite (and if you see errors, run it with <var>-v 3</var>)<br />
<var>troggle$ python manage.py test [-v 3]</var><br>
<li>Read all the release notes for <em>all</em> the intermediate releases. So from 1.1.29 we read <a href="https://docs.djangoproject.com/en/3.0/releases/">14 sets of notes</a>: for <a href="https://docs.djangoproject.com/en/3.0/releases/2.0/">2.0</a>, 2.0.1, 2.0.2... up to 2.0.13 .
<li>Seriously learn how to use the traceback webpage produced by django when a page crashes. There is a full record of every variable value hidden in there.
<li>You will be doing a lot of local testing just on your development machine. The default is to use the webserver built into Django: <var>python manage.py runserver 0.0.0.0:8000 -v 3</var>. Alternatively you can install and use gunicorn:
<var><a href="https://docs.gunicorn.org/en/stable/design.html">gunicorn</a> --reload -w 9 -b :8000 wsgi</var>. the '-w' flag is for the number of worker threads and should be 2n+1 where n is the number of cpu cores on your machine.
</ol>
<h3>Deprecation warnings and python versions</h3>
<p>The individual releases within a minor version don't break anything but do fix bugs. So if you are on 1.10.x there is no point in getting 1.11.1 to work and you should go straight to 1.11.29 .
<p><var>check --deploy</var> gives django warnings about security issues in your settings as well as django deprecation warnings.<br>
<var>-Wall</var> is a standard python option and gives warnings of deprecated python features used by django and all the current plugins. So it tells us that django 1.11.29 is using a deprecated python language feature which will be removed from the language in python 3.9 . Python version compatibilities are documented at the top of each x.0 release note. From Django 3.0 it requires python 3.6.
<h3>The upgrade process</h3>
<ol>
<li>ensure that you have the exact version of python installed on your machine as is live for troggle on the server, e.g. do <var>$ sudo apt install python3.7.5</var>.
<li>create a venv using the version of python to be used.
<li>do <a href="/repositories/troggle/.git/tree/README.txt">a clean install</a> of django and troggle using pip.
<li>check the versions of plugins using <var>pip list -o</a>
<li>open two terminal windows:
<ul>
<li>- one will be used for installations and tests.
<li>- the other one will be used for <var>python manage.py runserver 0.0.0.0:8000 -v 3</var> (or whatever portnumber you like)
</ul>
<li>rename the most recent localsettingsXXX.py to fit your local system and copy it to localsettings.py
<li>run a script to make a sanitised copy (no passwords) of localsettings.py as localsettingsXXX.py before every commit
<li>edit your localsettings.py to use sqlite with a file <var>troggle.sqlite</var>
<li>edit your localsettings.py to set a password for users "expo" & "expoadmin" (or just use default "nnn:gggggg")
<li>testing:
<ul>
<li>run <var>troggle$ python manage.py test</var>
<li>run the full data import <var>troggle$ python databaseReset.py reset R000</var>. It should take about 80 seconds to import everything.
<li>start the runserver in the other terminal window and open a web browser to http://localhost:8000 and check important pages which we don't have tests for (yet):
<br>- <var><a href="http://localhost:8000/pathsreport">http://localhost:8000/pathsreport</a></var>
<br>- <var><a href="http://localhost:8000/stats">http://localhost:8000/stats</a></var>
<br>- <var><a href="http://localhost:8000/people">http://localhost:8000/people</a></var>
<br>- <var><a href="http://localhost:8000/expedition/2018">http://localhost:8000/expedition/2018</a></var>
<br>- <var><a href="http://localhost:8000/expofiles/surveyscans/2019/walletindex.html">http://localhost:8000/expofiles/surveyscans/2019/walletindex.html</a></var>
<br>- <var><a href="http://localhost:8000/survey_scans/">http://localhost:8000/survey_scans/</a></var>
<br>- <var><a href="http://localhost:8000/survexfile/caves/">http://localhost:8000/survexfile/caves/</a></var>
<br>- <var><a href="http://localhost:8000/dwgdata/">http://localhost:8000/dwgdata/</a></var>
<br>- <var><a href="http://localhost:8000/expofiles/rigging_topos/264/entrance_topo_2016.pdf">http://localhost:8000/expofiles/rigging_topos/264/entrance_topo_2016.pdf</a></var>
<br>- <var><a href="http://localhost:8000/expofiles/rigging_topos/264/entrance_topo_2016.svg">http://localhost:8000/expofiles/rigging_topos/264/entrance_topo_2016.svg</a></var>
<br>- <var><a href="http://localhost:8000/expofiles/rigging_topos/264/entrance_topo1_2016.jpeg">http://localhost:8000/expofiles/rigging_topos/264/entrance_topo1_2016.jpeg</a></var>
<br>- <var><a href="http://localhost:8000/expofiles/training-info/Idiots guide to accessing expo git.pptx">http://localhost:8000/expofiles/training-info/Idiots guide to accessing expo git.pptx</a></var>
<br>- <var><a href="http://localhost:8000/1623/291/291.html">http://localhost:8000/1623/291/291.htm</a></var>
<br>- <var><a href="http://localhost:8000/caves">http://localhost:8000/caves</a></var>
<br>- <var><a href="http://localhost:8000/admin/doc/models/core.expedition/">ttp://localhost:8000/admin/doc/models/core.expedition/</a></var> (admin login required)
<br>- <var><a href="http://localhost:8000/survexfile/204">http://localhost:8000/survexfile/204</a></var>
</ul>
<li>Use the error dump tracebacks to find and correct the python code. [Running the server in a debugger would help: please add those instructioons for that to this page.]
<li>run the script <var>./pre-run.sh</var> to clean up everything before the next round of tests.
</ol>
<h3>Django dependencies</h3>
<p>You can upgrade the version of python installed within pip venv but not downgrade. So get that first venv installed right.
<p>Here is example of installed (Version) and most-recent-available (Latest) verisons of pip installations.
<pre><code>Package Version Latest Type
---------- ------- ------ -----
Django 2.2.19 3.2 wheel
docutils 0.14 0.17 wheel</code></pre>
<p>This only gives any output for packages which are not the most recent. To see what is actually installed use
<pre><code>$ pip freeze
confusable-homoglyphs==3.2.0
Django==2.2.19
docutils==0.17
Pillow==8.2.0
pytz==2021.1
sqlparse==0.4.1
Unidecode==1.2.0</code></pre>
Although the above all work fine, on debian <var>buster</var> we are actually using the standard installs which are older:
<pre><code>$ pip freeze
confusable-homoglyphs==3.2.0
Django==2.2.19
docutils==0.14
Pillow==5.4.1
pytz==2019.1
sqlparse==0.2.4
Unidecode==1.0.23</code></pre>
<p>To upgrade pip istelf, do <var>$ pip install --upgrade pip</var>
<h3>Django database dependencies</h3>
<p>On the expo server we run MariaDB as the database which has its own dependencies. In particular
<pre><code>mysqlclient==1.3.10
</code></pre>which is technically incompatible with Django 2.2 which requires 1.3.13. This incompatibility is a policy choice by the Django team. Wookey ran the Django system tests with this (April 2020) and it works fine.
<h4>To run Django's system test suite:</h4>
Follow the instructions in the "Unit tests" section installed locally at docs/internals/contributing/writing-code/unit-tests.txt, published online at <a href="https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/#running-the-unit-tests">docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/</a>
This involves running <var>git clone</var> on the django source repo to download the tests. We hope we never have to do this again but in case we get incomprehensible bugs in future, we should be prepared to do so.
<hr />
<p>We should not need to anything until we move from django 2.2 LTS to 3.2 LTS which <a href="trog2030.html">we may never do</a>.
<p>Current upgrade status is documented: <a href="trogstatus.html">here</a>.
<p>
Go on to: <a href="trogarch.html">Troggle architecture</a><br />
Return to: <a href="trogintro.html">Troggle intro</a><br />
Troggle index:
<a href="trogindex.html">Index of all troggle documents</a><br />
<hr />
</body>
</html>