diff --git a/README.rst b/README.rst
index 23c832be25da4b4257647a4307cb892d4305f99d..cc072c496afa7019105dd23e7881331d1599dc25 100644
--- a/README.rst
+++ b/README.rst
@@ -141,6 +141,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 Change history
 --------------
 
+Version 2.29.1 (12/07/2017)
+
+- Fix to generation of code to export child elements that have
+  default values.  When the element's value is equal to the default
+  value, the export of the element should be omitted only if the
+  element is optional (i.e. minOccurs=0).  Thanks to Andrii Iudin
+  for reporting this.
+- Several modifications to use the `six` module as a cleaner way to
+  smooth over differences between Python 2 and Python 3.
+- Added file generateds/django/README.txt containing instructions on
+  running the Django code generation support.  Thanks to Christian
+  González for reporting problems with this and for providing
+  information that helped understanding the source of the
+  difficulties.
+
 Version 2.29.0 (11/28/2017)
 
 - Fixes to export of namespace prefixes for schemas that are
diff --git a/django/README.txt b/django/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ed0d67d1093040cec5763c5e9888827c4cc79810
--- /dev/null
+++ b/django/README.txt
@@ -0,0 +1,51 @@
+============================================
+Instructions on running the Django support
+============================================
+
+Also see:
+http://www.davekuhlman.org/generateDS.html#django-generating-models-and-forms
+
+Although, there are likely other configurations that will work, one
+reasonably simple way is the following:
+
+1. Download the source distribution of generateDS with the
+   following::
+
+       $ hg clone https://dkuhlman@bitbucket.org/dkuhlman/generateds
+
+   Alternatively, you can download a Zip file from here:
+   https://bitbucket.org/dkuhlman/generateds/downloads/
+
+   Or, a tar file from here:
+   https://pypi.python.org/pypi/generateDS
+
+   And, then unroll it.
+
+2. Change directory to the ``django`` directory (i.e. the directory
+   containing this file)::
+
+       $ cd generateds/django
+
+3. In that directory, either, (a) create, a symbolic link to
+   ``generateDS.py``::
+
+       $ ln -s ../generateDS.py
+
+   Or, (b) copy ``generateDS.py`` to that directory::
+
+       $ cp ../generateDS.py .
+
+4. In that directory, Run ``gends_run_gen_django.py``.  For
+   example::
+
+       $ cp ../tests/people.xsd .
+       $ ./gends_run_gen_django.py -f -v people.xsd
+
+If the above ran successfully, it should have created these files::
+
+    models.py
+    forms.py
+    admin.py
+
+
+.. vim:ft=rst:
diff --git a/django/generatedssuper.py b/django/generatedssuper.py
index 62f4d33890ee6af636c62a12e6ab228b1c329721..05c577e9c58389a97ea422492aebdfe3560b58d2 100644
--- a/django/generatedssuper.py
+++ b/django/generatedssuper.py
@@ -218,9 +218,9 @@ class GeneratedsSuper(object):
                     wrtforms('    %s = forms.TimeField(%s)\n' % (
                         name, options, ))
                 elif data_type in Boolean_type_table:
-                    wrtmodels('    %s = models.BooleanField(%s)\n' % (
+                    wrtmodels('    %s = models.NullBooleanField(%s)\n' % (
                         name, options, ))
-                    wrtforms('    %s = forms.BooleanField(%s)\n' % (
+                    wrtforms('    %s = forms.NullBooleanField(%s)\n' % (
                         name, options, ))
                 elif data_type in String_type_table:
                     wrtmodels(
diff --git a/generateDS.py b/generateDS.py
index 3da466212e3ec20905eda9cddc3d7133e25f444f..2e7a2ff7fd61fcced02955e9b8dca10cad9d0856 100755
--- a/generateDS.py
+++ b/generateDS.py
@@ -173,10 +173,20 @@ also generates member specifications in each class (in a dictionary).
 
 
 from __future__ import print_function
+from six.moves import input
+import six
 import sys
 import os.path
 import time
 import getopt
+import imp
+from xml.sax import handler, make_parser
+import logging
+import keyword
+import textwrap
+import hashlib
+import operator
+import re
 
 if sys.version_info.major == 2:
     import urllib2
@@ -187,14 +197,6 @@ else:
     import urllib.parse
     import io
     from functools import reduce
-import imp
-from xml.sax import handler, make_parser
-import logging
-import keyword
-import textwrap
-import hashlib
-import operator
-import re
 
 # Default logger configuration
 logging.basicConfig(
@@ -227,14 +229,10 @@ logging.disable(logging.INFO)
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.29.0'
+VERSION = '2.29.1'
 ##VERSION##
 
-if sys.version_info.major == 2:
-    BaseStrType = basestring
-else:
-    BaseStrType = str
-
+BaseStrTypes = six.string_types
 GenerateProperties = 0
 UseGetterSetter = 'new'
 UseOldSimpleTypeValidators = False
@@ -2006,12 +2004,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
     else:
         child_ns = namespace
     if child_type == DateTimeType:
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != "%s":\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
             "(self.gds_format_datetime(self.%s, " \
@@ -2019,12 +2012,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
             (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == DateType:
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != "%s":\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
             "(self.gds_format_date(self.%s, " \
@@ -2032,12 +2020,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
             (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == TimeType:
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != "%s":\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
             "(self.gds_format_time(self.%s, " \
@@ -2047,12 +2030,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
     elif (child_type in StringType or
             child_type == TokenType or
             child_type in DateTimeGroupType):
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != "%s":\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         # fixlist
         if (child.getSimpleType() in SimpleTypeDict and
@@ -2080,12 +2058,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
             child_type == NonPositiveIntegerType or
             child_type == NegativeIntegerType or
             child_type == NonNegativeIntegerType):
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != %s:\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         if child.isListType():
             s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
@@ -2099,17 +2072,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
                 (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == BooleanType:
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            if default == 'true':
-                wrt('%s        if not self.%s:\n' % (fill, mappedName, ))
-            elif default == 'false':
-                wrt('%s        if self.%s:\n' % (fill, mappedName, ))
-            else:
-                wrt('%s        if self.%s is not None:\n' % (
-                    fill, mappedName, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         if child.isListType():
             s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
@@ -2125,12 +2088,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
         wrt(s1)
     elif (child_type == FloatType or
             child_type == DecimalType):
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != %s:\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         if child.isListType():
             s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
@@ -2144,12 +2102,7 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
                 (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == DoubleType:
-        default = child.getDefault()
-        if default is None:
-            wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
-        else:
-            wrt('%s        if self.%s != %s:\n' % (
-                fill, mappedName, default, ))
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
         if child.isListType():
             s1 = "%s            outfile.write('<%s%s>%%s</%s%s>%%s' %% " \
@@ -2319,8 +2272,8 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
     else:
         child_ns = namespace
     # fix_simpletype
+    default = child.getDefault()
     if child_type == DateTimeType:
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2333,7 +2286,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
             (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == DateType:
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2346,7 +2298,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
             (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == TimeType:
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2361,7 +2312,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
     elif (child_type in StringType or
             child_type == TokenType or
             child_type in DateTimeGroupType):
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2388,7 +2338,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
             child_type == NonPositiveIntegerType or
             child_type == NegativeIntegerType or
             child_type == NonNegativeIntegerType):
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2407,7 +2356,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
                 (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == BooleanType:
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2430,11 +2378,10 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
                 "(self.gds_format_boolean(" \
                 "self.%s, input_name='%s'), " \
                 "eol_))\n" % (
-                fill, child_ns, name, child_ns, name, mappedName, name)
+                    fill, child_ns, name, child_ns, name, mappedName, name)
         wrt(s1)
     elif (child_type == FloatType or
             child_type == DecimalType):
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -2453,7 +2400,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
                 (fill, child_ns, name, child_ns, name, mappedName, name, )
         wrt(s1)
     elif child_type == DoubleType:
-        default = child.getDefault()
         if default is None:
             wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
         else:
@@ -6789,12 +6735,8 @@ def makeFile(outFileName):
                 outFileName)
             sys.exit('Exiting.  No output file.')
         else:
-            if sys.version_info.major == 2:
-                reply = raw_input(
-                    'File %s exists.  Overwrite? (y/n): ' % outFileName)
-            else:
-                reply = input(
-                    'File %s exists.  Overwrite? (y/n): ' % outFileName)
+            reply = input(
+                'File %s exists.  Overwrite? (y/n): ' % outFileName)
             if reply == 'y':
                 outFile = open(outFileName, 'w')
             else:
@@ -7126,8 +7068,8 @@ def capture_cleanup_name_list(option):
         if sys.version_info.major == 2:
             if (type(cleanup_pair) not in (list, tuple) or
                     len(cleanup_pair) != 2 or
-                    not isinstance(cleanup_pair[0], BaseStrType) or
-                    not isinstance(cleanup_pair[1], BaseStrType)):
+                    not isinstance(cleanup_pair[0], BaseStrTypes) or
+                    not isinstance(cleanup_pair[1], BaseStrTypes)):
                 raise RuntimeError(
                     'Option --cleanup-name-list contains '
                     'invalid element.')
diff --git a/generateDS.txt b/generateDS.txt
index 371b9b616b51c6df5d05ba225a71f4c63ea9657f..46bbdf0be11fe600fae971c28c3815f8b34bfb7d 100644
--- a/generateDS.txt
+++ b/generateDS.txt
@@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema
 
 .. version
 
-:revision: 2.29.0
+:revision: 2.29.1
 
 .. version
 
diff --git a/generateds_gui_notes.txt b/generateds_gui_notes.txt
index af38d1abfc456bca97977def933e008613fe5561..0c0919db9a3ba009fd3f3e3f2deaa5587ea8caa7 100644
--- a/generateds_gui_notes.txt
+++ b/generateds_gui_notes.txt
@@ -12,7 +12,7 @@ GenerateDS GUI Notes
 
 .. version
 
-:revision: 2.29.0
+:revision: 2.29.1
 
 .. version
 
diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py
index bf670dcbaf872e54d4f03314b74e3144fa733862..6d96b4accfe9ec24de7f9d33b569d8127bbeccd8 100644
--- a/gui/generateds_gui.py
+++ b/gui/generateds_gui.py
@@ -41,7 +41,7 @@ from libgenerateDS.gui import generateds_gui_session
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.29.0'
+VERSION = '2.29.1'
 ##VERSION##
 
 
diff --git a/librarytemplate_howto.txt b/librarytemplate_howto.txt
index e732d840aead57223eff7154590f4a638820c20f..6caf9015b29445cbe975e75c290de99d4f75e01f 100644
--- a/librarytemplate_howto.txt
+++ b/librarytemplate_howto.txt
@@ -8,7 +8,7 @@ How to package a generateDS.py generated library
 
 .. version
 
-:revision: 2.29.0
+:revision: 2.29.1
 
 .. version
 
diff --git a/process_includes.py b/process_includes.py
index 7b54239b926f868aabf9035846ab30234656d152..734d6a0af178123f320bdac3a8f8a0620e278c75 100644
--- a/process_includes.py
+++ b/process_includes.py
@@ -40,7 +40,7 @@ except ImportError:
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.29.0'
+VERSION = '2.29.1'
 ##VERSION##
 
 CatalogDict = {}
diff --git a/setup.py b/setup.py
index 4bf3b43d2612f5862dbcb7870b8e461e5b567b3f..98670f662d4135640f5f1645c66bb5d79979e42f 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ setup(name="generateDS",
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-    version="2.29.0",
+    version="2.29.1",
 ##VERSION##
     author="Dave Kuhlman",
     author_email="dkuhlman@davekuhlman.org",
diff --git a/tests/check_results.rb b/tests/check_results.rb
index 015c7b3c7dd6678bc87e10f4ea97ad773fdd67d5..38f9fbe9094996bf7017df0925451edde01e985e 100755
--- a/tests/check_results.rb
+++ b/tests/check_results.rb
@@ -71,6 +71,8 @@ $commands = [
   "diff -u catalogtest1_sup.py catalogtest2_sup.py",
   "diff -u disable_xml_super1_sub.py disable_xml_super2_sub.py",
   "diff -u disable_xml_super1_sup.py disable_xml_super2_sup.py",
+  "diff -u defaults_cases_export1_sub.py defaults_cases_export2_sub.py",
+  "diff -u defaults_cases_export1_sup.py defaults_cases_export2_sup.py",
 ]
 
 def check
diff --git a/tests/copy_all b/tests/copy_all
index 70abfa96c2b3b052d1a0a854668959969f0597ea..4c9eeb6aac749b6b3f8c923069b49e445abe1acb 100755
--- a/tests/copy_all
+++ b/tests/copy_all
@@ -59,3 +59,5 @@ cp rem_dup_elems2_sup.py rem_dup_elems1_sup.py
 cp rem_dup_elems2_sub.py rem_dup_elems1_sub.py
 cp disable_xml_super2_sup.py disable_xml_super1_sup.py
 cp disable_xml_super2_sub.py disable_xml_super1_sub.py
+cp defaults_cases_export2_sub.py defaults_cases_export1_sub.py
+cp defaults_cases_export2_sup.py defaults_cases_export1_sup.py
diff --git a/tests/test.py b/tests/test.py
index 66d69bb52a35ba2309d30a7e1fb099757582a434..0007f1707abb1e3caae1cee7fce712f99e039a33 100755
--- a/tests/test.py
+++ b/tests/test.py
@@ -922,7 +922,7 @@ def main():
     args = sys.argv[1:]
     try:
         opts, args = getopt.getopt(args, 'h', ['help'])
-    except:
+    except getopt.GetoptError:
         usage()
     for opt, val in opts:
         if opt in ('-h', '--help'):
diff --git a/tutorial/generateds_tutorial.txt b/tutorial/generateds_tutorial.txt
index e49dea9cbe20cbca39f64c6bd15991297fb93b66..e3f298b70a6aec16b52cfe55429949b56f17f61e 100644
--- a/tutorial/generateds_tutorial.txt
+++ b/tutorial/generateds_tutorial.txt
@@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial
 
 .. version
 
-:revision: 2.29.0
+:revision: 2.29.1
 
 .. version
 
diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip
index 5df17e9bc8cbf7303ea98cf29479ce020d3d7253..72796061feaf3b438d4142cfb29f8a3a26b7eb17 100644
Binary files a/tutorial/generateds_tutorial.zip and b/tutorial/generateds_tutorial.zip differ