Repository: City-of-Helsinki/linkedevents

Issue:
Use ArgumentParser instead of deprecated OptionParser in management commands
`python manage.py event_import yso --keywords`  warns:
`RemovedInDjango110Warning: OptionParser usage for Django management commands is deprecated, use ArgumentParser instead`.

Use ArgumentParser instead of deprecated OptionParser in management commands to ensure compatibility with Django 1.10.

E.g. https://github.com/City-of-Helsinki/linkedevents/blob/master/events/management/commands/event_import.py#L2



Discussion:
Migration seems pretty easy, just replace

```
    option_list = list(BaseCommand.option_list + (
        make_option('--all', action='store_true', dest='all', help='Import all entities'),
        make_option('--cached', action='store_true', dest='cached', help='Cache requests (if possible)'),
        make_option('--single', action='store', dest='single', help='Import only single entity'),
    ))
```

with

```
    def add_arguments(self, parser):
        parser.add_argument(kwargs_1)
        parser.add_argument(kwargs_2)
        parser.add_argument(kwargs_3)
```

Must verify this, though.


Resolving patch:
diff --git a/events/management/commands/event_export.py b/events/management/commands/event_export.py
--- a/events/management/commands/event_export.py
+++ b/events/management/commands/event_export.py
@@ -8,55 +8,50 @@
 
 
 class Command(BaseCommand):
-    args = '<module>'
     help = "Export event data"
-    option_list = list(BaseCommand.option_list + (
-        make_option('--new', action='store_true', dest='new',
-                    help='Export entities added after last export date'),
-        make_option('--delete', action='store_true', dest='delete',
-                    help='Delete exported items from target system'),
-    ))
 
     exporter_types = ['events']
 
     def __init__(self):
-        super(Command, self).__init__()
-        for imp in self.exporter_types:
-            opt = make_option('--%s' % imp, dest=imp, action='store_true',
-                              help='export %s' % imp)
-            self.option_list.append(opt)
+        super().__init__()
+        self.exporters = get_exporters()
+        self.exp_list = ', '.join(sorted(self.exporters.keys()))
+        self.missing_args_message = "Enter the name of the event exporter module. Valid exporters: %s" % self.exp_list
+
+    def add_arguments(self, parser):
+        parser.add_argument('module')
+        parser.add_argument('--new', action='store_true', dest='new',
+                            help='Export entities added after last export date')
+        parser.add_argument('--delete', action='store_true', dest='delete',
+                            help='Delete exported items from target system')
+        for exp in self.exporter_types:
+            parser.add_argument('--%s' % exp, dest=exp, action='store_true', help='export %s' % exp)
 
     def handle(self, *args, **options):
-        importers = get_exporters()
-        imp_list = ', '.join(sorted(importers.keys()))
-        if len(args) != 1:
-            raise CommandError(
-                "Enter the name of the event exporter module. "
-                "Valid exporters: %s" % imp_list)
-        if not args[0] in importers:
-            raise CommandError("Exporter %s not found. Valid exporters: %s"
-                               % (args[0], imp_list))
-        imp_class = importers[args[0]]
+        module = options['module']
+        if not module in self.exporters:
+            raise CommandError("Exporter %s not found. Valid exporters: %s" % (module, self.exp_list))
+        exp_class = self.exporters[module]
 
         if hasattr(settings, 'PROJECT_ROOT'):
             root_dir = settings.PROJECT_ROOT
         else:
             root_dir = settings.BASE_DIR
-        exporter = imp_class()
+        exporter = exp_class()
 
-        # Activate the default language for the duration of the import
+        # Activate the default language for the duration of the export
         # to make sure translated fields are populated correctly.
         old_lang = get_language()
         activate(settings.LANGUAGES[0][0])
 
-        for imp_type in self.exporter_types:
-            name = "export_%s" % imp_type
+        for exp_type in self.exporter_types:
+            name = "export_%s" % exp_type
             method = getattr(exporter, name, None)
-            if options[imp_type]:
+            if options[exp_type]:
                 if not method:
                     raise CommandError(
                         "Exporter %s does not support exporter %s"
-                        % (name, imp_type))
+                        % (name, exp_type))
             else:
                 if not options['new'] and not options['delete']:
                     continue
diff --git a/events/management/commands/event_import.py b/events/management/commands/event_import.py
--- a/events/management/commands/event_import.py
+++ b/events/management/commands/event_import.py
@@ -8,30 +8,30 @@
 
 
 class Command(BaseCommand):
-    args = '<module>'
     help = "Import event data"
-    option_list = list(BaseCommand.option_list + (
-        make_option('--all', action='store_true', dest='all', help='Import all entities'),
-        make_option('--cached', action='store_true', dest='cached', help='Cache requests (if possible)'),
-        make_option('--single', action='store', dest='single', help='Import only single entity'),
-    ))
 
     importer_types = ['places', 'events', 'keywords']
 
     def __init__(self):
-        super(Command, self).__init__()
+        super().__init__()
+        self.importers = get_importers()
+        self.imp_list = ', '.join(sorted(self.importers.keys()))
+        self.missing_args_message = "Enter the name of the event importer module. Valid importers: %s" % self.imp_list
+
+    def add_arguments(self, parser):
+        parser.add_argument('module')
+        parser.add_argument('--all', action='store_true', dest='all', help='Import all entities')
+        parser.add_argument('--cached', action='store_true', dest='cached', help='Cache requests (if possible)')
+        parser.add_argument('--single', action='store', dest='single', help='Import only single entity')
+
         for imp in self.importer_types:
-            opt = make_option('--%s' % imp, dest=imp, action='store_true', help='import %s' % imp)
-            self.option_list.append(opt)
+            parser.add_argument('--%s' % imp, dest=imp, action='store_true', help='import %s' % imp)
 
     def handle(self, *args, **options):
-        importers = get_importers()
-        imp_list = ', '.join(sorted(importers.keys()))
-        if len(args) != 1:
-            raise CommandError("Enter the name of the event importer module. Valid importers: %s" % imp_list)
-        if not args[0] in importers:
-            raise CommandError("Importer %s not found. Valid importers: %s" % (args[0], imp_list))
-        imp_class = importers[args[0]]
+        module = options['module']
+        if not module in self.importers:
+            raise CommandError("Importer %s not found. Valid importers: %s" % (module, self.imp_list))
+        imp_class = self.importers[module]
 
         if hasattr(settings, 'PROJECT_ROOT'):
             root_dir = settings.PROJECT_ROOT


Test patch: