{"id":899,"date":"2017-09-27T03:41:59","date_gmt":"2017-09-27T03:41:59","guid":{"rendered":"http:\/\/timony.com\/mickzblog\/?p=899"},"modified":"2017-09-27T03:45:37","modified_gmt":"2017-09-27T03:45:37","slug":"migrate-django-1-4-to-1-11","status":"publish","type":"post","link":"http:\/\/timony.com\/mickzblog\/2017\/09\/27\/migrate-django-1-4-to-1-11\/","title":{"rendered":"Migrate Django 1.4 to 1.11"},"content":{"rendered":"<p>I thought these rough notes might be useful to anyone migrating from Django 1.4 (and possibly 1.3) to Django 1.11.<\/p>\n<h1 class=\"p1\"><b>Moving from South to Django Migrations<\/b><\/h1>\n<h3 class=\"p1\">1. Update your settings files:<\/h3>\n<p class=\"p1\">Remove \u2018south\u2019 from your INSTALLED_APPS<\/p>\n<h3 class=\"p1\">2. Remove migrations.<\/h3>\n<p class=\"p1\">Remove all app\/migrations files except for __initi__.py . Remove any *.py[c|o] files.<\/p>\n<p class=\"p1\">Make sure there\u2019s no migrations specific code in your app\/migrations\/__init__.py files<\/p>\n<p class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.7\/topics\/migrations\/\">https:\/\/docs.djangoproject.com\/en\/1.7\/topics\/migrations\/<\/a><\/p>\n<h3>3. Run new Migrations<\/h3>\n<pre class=\"p1\">python manage.py makemigrations;\r\n\r\npython manage.py migrate;<\/pre>\n<h1 class=\"p1\"><b>Moving from Django 1.3\/1.4 -&gt; 1.11<\/b><\/h1>\n<p class=\"p1\">This is a 1.3 app migrated to 1.4 and now is being migrated to 1.11.<\/p>\n<p class=\"p1\">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.<\/p>\n<h3><b>URLS files:<\/b><\/h3>\n<p class=\"p3\">django.conf.urls.defaults<span class=\"s1\"> is replaced by <\/span>django.conf.urls<\/p>\n<p class=\"p1\">patterns() is gone, see:<\/p>\n<p class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.8\/#django-conf-urls-patterns\">https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.8\/#django-conf-urls-patterns<\/a><\/p>\n<h3>Views<\/h3>\n<h4>django.views.generic.simple<\/h4>\n<p class=\"p1\">django.views.generic.simple is gone, removed in 1.5.<\/p>\n<p class=\"p1\">Replace django.views.generic.simple.direct_to_template with TemplateView:<\/p>\n<pre class=\"p4\"><span class=\"s2\">from<\/span> django.views.generic <span class=\"s2\">import<\/span> <span class=\"s3\">TemplateView\r\n<\/span><\/pre>\n<h3 class=\"p1\"><b>Shortcuts<\/b><\/h3>\n<pre class=\"p4\"><span class=\"s2\">from<\/span> django.shortcuts <span class=\"s2\">import<\/span> <span class=\"s3\">RequestContext<\/span><\/pre>\n<p class=\"p1\">Replaced with:<\/p>\n<pre class=\"p4\"><span class=\"s2\">from<\/span> django.template <span class=\"s2\">import<\/span> <span class=\"s3\">RequestContext<\/span><\/pre>\n<h3>Contrib<\/h3>\n<p class=\"p1\">django.contrib.databrowse is gone. See:<\/p>\n<ul>\n<li class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.4\/#django-contrib-databrowse\">https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.4\/#django-contrib-databrowse<\/a><\/li>\n<\/ul>\n<h3><b>Forms<\/b><\/h3>\n<p class=\"p1\">This error:<\/p>\n<pre class=\"p1\">django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form BlahForm needs updating.<\/pre>\n<p class=\"p1\">Change in Django 1.8. See:<\/p>\n<ul>\n<li class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.8\/topics\/forms\/modelforms\/#selecting-the-fields-to-use\">https:\/\/docs.djangoproject.com\/en\/1.8\/topics\/forms\/modelforms\/#selecting-the-fields-to-use<\/a><\/li>\n<\/ul>\n<p class=\"p1\">Quick fix is:<\/p>\n<pre class=\"p4\">fields = <span class=\"s4\">'__all__'<\/span><\/pre>\n<p class=\"p1\">But you will need to confirm that you want the form to expose all fields.<\/p>\n<h4>Formtools<\/h4>\n<p class=\"p1\">Removal of django.contrib.formtools:<\/p>\n<p class=\"p1\">Is now separate package, install with pip:<\/p>\n<pre class=\"p3\">pip install django-formtools<\/pre>\n<p class=\"p1\">Change imports from django.contrib.formtools to formtools. For example:<\/p>\n<pre class=\"p4\"><span class=\"s2\">from<\/span> django.contrib.formtools.preview <span class=\"s2\">import<\/span> <span class=\"s3\">FormPreview<\/span><\/pre>\n<p class=\"p1\">Becomes:<\/p>\n<pre class=\"p4\"><span class=\"s2\">from<\/span> formtools.preview <span class=\"s2\">import<\/span> <span class=\"s3\">FormPreview<\/span><\/pre>\n<h3 class=\"p1\"><b>Models<\/b><\/h3>\n<p class=\"p1\">model._meta.get_all_field_names() is gone.<\/p>\n<p class=\"p1\">See:<\/p>\n<p class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.9\/ref\/models\/meta\/#migrating-from-the-old-api\">https:\/\/docs.djangoproject.com\/en\/1.9\/ref\/models\/meta\/#migrating-from-the-old-api<\/a><\/p>\n<p>This is verbatim from the docs:<\/p>\n<p style=\"padding-left: 30px;\"><code class=\"docutils literal\"><span class=\"pre\">MyModel._meta.get_all_field_names()<\/span><\/code>\u00a0<em>becomes<\/em>:<\/p>\n<div class=\"highlight-default\" style=\"padding-left: 30px;\">\n<div class=\"highlight\" style=\"padding-left: 30px;\">\n<pre style=\"padding-left: 30px;\"><span class=\"kn\">from<\/span> <span class=\"nn\">itertools<\/span> <span class=\"k\">import<\/span> <span class=\"n\">chain<\/span>\r\n<span class=\"nb\">list<\/span><span class=\"p\">(<\/span><span class=\"nb\">set<\/span><span class=\"p\">(<\/span><span class=\"n\">chain<\/span><span class=\"o\">.<\/span><span class=\"n\">from_iterable<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"p\">(<\/span><span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">name<\/span><span class=\"p\">,<\/span> <span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">attname<\/span><span class=\"p\">)<\/span> <span class=\"k\">if<\/span> <span class=\"nb\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">field<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'attname'<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"p\">(<\/span><span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">name<\/span><span class=\"p\">,)<\/span>\r\n    <span class=\"k\">for<\/span> <span class=\"n\">field<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">MyModel<\/span><span class=\"o\">.<\/span><span class=\"n\">_meta<\/span><span class=\"o\">.<\/span><span class=\"n\">get_fields<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"c1\"># For complete backwards compatibility, you may want to exclude<\/span>\r\n    <span class=\"c1\"># GenericForeignKey from the results.<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"p\">(<\/span><span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">many_to_one<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">field<\/span><span class=\"o\">.<\/span><span class=\"n\">related_model<\/span> <span class=\"ow\">is<\/span> <span class=\"kc\">None<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">)))<\/span>\r\n<\/pre>\n<\/div>\n<\/div>\n<p style=\"padding-left: 30px;\">This provides a 100% backwards compatible replacement, ensuring that both field names and attribute names\u00a0<code class=\"docutils literal\"><span class=\"pre\">ForeignKey<\/span><\/code>s are included, but fields associated with\u00a0<code class=\"docutils literal\"><span class=\"pre\">GenericForeignKey<\/span><\/code>s are not. A simpler version would be:<\/p>\n<div class=\"highlight-default\" style=\"padding-left: 30px;\">\n<div class=\"highlight\" style=\"padding-left: 30px;\">\n<pre style=\"padding-left: 30px;\"><span class=\"p\">[<\/span><span class=\"n\">f<\/span><span class=\"o\">.<\/span><span class=\"n\">name<\/span> <span class=\"k\">for<\/span> <span class=\"n\">f<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">MyModel<\/span><span class=\"o\">.<\/span><span class=\"n\">_meta<\/span><span class=\"o\">.<\/span><span class=\"n\">get_fields<\/span><span class=\"p\">()]<\/span>\r\n<\/pre>\n<\/div>\n<\/div>\n<p style=\"padding-left: 30px;\">While this isn\u2019t 100% backwards compatible, it may be sufficient in many situations.<\/p>\n<h3 class=\"p1\"><b>Commands<\/b><\/h3>\n<h4>BaseCommand<\/h4>\n<p class=\"p1\">BaseCommand.option_list is gone.<\/p>\n<p class=\"p1\">See <a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.8\/#extending-management-command-arguments-through-command-option-list\">https:\/\/docs.djangoproject.com\/en\/1.11\/releases\/1.8\/#extending-management-command-arguments-through-command-option-list<\/a> .<\/p>\n<h4>Arguments<\/h4>\n<p class=\"p1\">See here for how to add arguments:<\/p>\n<p class=\"p1\"><a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/howto\/custom-management-commands\/#custom-commands-options\">https:\/\/docs.djangoproject.com\/en\/1.11\/howto\/custom-management-commands\/#accepting-optional-arguments<\/a><\/p>\n<p class=\"p11\"><span class=\"s5\">These custom options can be added in the <a href=\"https:\/\/docs.djangoproject.com\/en\/1.11\/howto\/custom-management-commands\/#django.core.management.BaseCommand.add_arguments\"><b>add_arguments()<\/b><\/a> method like this:<\/span><\/p>\n<p class=\"p8\"><span class=\"s9\"><b>class<\/b><\/span> <span class=\"s8\"><b>Command<\/b><\/span><span class=\"s5\">(BaseCommand):<\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 <\/span><\/span><span class=\"s9\"><b>def<\/b><\/span> <span class=\"s8\">add_arguments<\/span><span class=\"s5\">(<\/span><span class=\"s9\">self<\/span><span class=\"s5\">, parser):<\/span><\/p>\n<p class=\"p9\"><span class=\"s7\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span><\/span><span class=\"s5\"><i># Positional arguments<\/i><\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>parser<\/span><span class=\"s10\">.<\/span><span class=\"s5\">add_argument(<\/span><span class=\"s11\">&#8216;poll_id&#8217;<\/span><span class=\"s5\">, nargs<\/span><span class=\"s10\">=<\/span><span class=\"s11\">&#8216;+&#8217;<\/span><span class=\"s5\">, <\/span><span class=\"s9\">type<\/span><span class=\"s10\">=<\/span><span class=\"s9\">int<\/span><span class=\"s5\">)<\/span><\/p>\n<p class=\"p9\"><span class=\"s7\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span><\/span><span class=\"s5\"><i># Named (optional) arguments<\/i><\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>parser<\/span><span class=\"s10\">.<\/span><span class=\"s5\">add_argument(<\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span><\/span><span class=\"s11\">&#8216;&#8211;delete&#8217;<\/span><span class=\"s5\">,<\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span>action<\/span><span class=\"s10\">=<\/span><span class=\"s11\">&#8216;store_true&#8217;<\/span><span class=\"s5\">,<\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span>dest<\/span><span class=\"s10\">=<\/span><span class=\"s11\">&#8216;delete&#8217;<\/span><span class=\"s5\">,<\/span><\/p>\n<p class=\"p8\"><span class=\"s5\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span>default<\/span><span class=\"s10\">=<\/span><span class=\"s9\"><b>False<\/b><\/span><span class=\"s5\">,<\/span><\/p>\n<p class=\"p13\"><span class=\"s7\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span>help<\/span><span class=\"s10\">=<\/span><span class=\"s5\">&#8216;Delete poll instead of closing it&#8217;<\/span><span class=\"s7\">,<\/span><\/p>\n<p class=\"p10\"><span class=\"s13\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>)<\/span><\/p>\n<h2 class=\"p1\"><b>Move from MySQL to Postgres<\/b><\/h2>\n<p class=\"p1\">Bigger or more complex databases may want to do a manual migration where the database is migration using django models.<\/p>\n<p class=\"p1\"><a href=\"https:\/\/www.calazan.com\/migrating-django-app-from-mysql-to-postgresql\/\">https:\/\/www.calazan.com\/migrating-django-app-from-mysql-to-postgresql\/<\/a><\/p>\n<p class=\"p1\">I&#8217;ll update this as I have time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 \u2018south\u2019 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\u2019s no &hellip; <a href=\"http:\/\/timony.com\/mickzblog\/2017\/09\/27\/migrate-django-1-4-to-1-11\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Migrate Django 1.4 to 1.11<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[685,33,665],"tags":[686,694,502,695],"class_list":["post-899","post","type-post","status-publish","format-standard","hentry","category-django","category-programming","category-python","tag-django","tag-django-1-11","tag-programming","tag-web-development"],"_links":{"self":[{"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/posts\/899","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/comments?post=899"}],"version-history":[{"count":10,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/posts\/899\/revisions"}],"predecessor-version":[{"id":920,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/posts\/899\/revisions\/920"}],"wp:attachment":[{"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/media?parent=899"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/categories?post=899"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/timony.com\/mickzblog\/wp-json\/wp\/v2\/tags?post=899"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}