From d1aed61b133a4b8292baa2d9fe7931fcd4188591 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Thu, 15 Jul 2021 12:11:27 +0200
Subject: [PATCH 1/4] misc: apply black (#54260)

---
 django_journal/actions.py                 |  14 ++-
 django_journal/admin.py                   |  69 +++++++------
 django_journal/decorator.py               |   5 +-
 django_journal/journal.py                 |  49 +++++-----
 django_journal/managers.py                |  54 +++++------
 django_journal/middleware.py              |  13 ++-
 django_journal/migrations/0001_initial.py |  56 +++++++++--
 django_journal/models.py                  | 113 +++++++++++-----------
 setup.py                                  |  57 +++++------
 test_settings.py                          |  16 ++-
 tests/test_main.py                        |  38 ++++++--
 11 files changed, 275 insertions(+), 209 deletions(-)

diff --git a/django_journal/actions.py b/django_journal/actions.py
index e5bdbf5..93016a6 100644
--- a/django_journal/actions.py
+++ b/django_journal/actions.py
@@ -8,6 +8,7 @@ from django.utils.encoding import force_text
 
 from . import models
 
+
 def export_as_csv_generator(queryset):
     header = ['time', 'tag', 'message']
     tags = set(models.Tag.objects.filter(objectdata__journal__in=queryset).values_list('name', flat=True))
@@ -15,13 +16,13 @@ def export_as_csv_generator(queryset):
         tags.add('%s__id' % tag)
     tags |= set(models.Tag.objects.filter(stringdata__journal__in=queryset).values_list('name', flat=True))
     extra_headers = list(sorted(tags))
-    yield header+extra_headers
+    yield header + extra_headers
     for journal in queryset:
         row = {
-                'time': journal.time.isoformat(' '),
-                'tag': force_text(journal.tag.name),
-                'message': force_text(journal),
-              }
+            'time': journal.time.isoformat(' '),
+            'tag': force_text(journal.tag.name),
+            'message': force_text(journal),
+        }
         for stringdata in journal.stringdata_set.all():
             row_name = stringdata.tag.name.encode('utf-8')
             row[force_text(row_name)] = force_text(stringdata.content)
@@ -34,6 +35,7 @@ def export_as_csv_generator(queryset):
                 row[row_name] = force_text(objectdata.content_object)
         yield row
 
+
 def export_as_csv(modeladmin, request, queryset):
     """
     CSV export for journal
@@ -47,4 +49,6 @@ def export_as_csv(modeladmin, request, queryset):
     for row in l:
         writer.writerow(row)
     return response
+
+
 export_as_csv.short_description = _(u"Export CSV file")
diff --git a/django_journal/admin.py b/django_journal/admin.py
index 638faec..28b0d57 100644
--- a/django_journal/admin.py
+++ b/django_journal/admin.py
@@ -13,8 +13,7 @@ from .actions import export_as_csv
 
 
 class ModelAdminFormatter(Formatter):
-    def __init__(self, model_admin=None, filter_link=True,
-            object_link=True):
+    def __init__(self, model_admin=None, filter_link=True, object_link=True):
         self.filter_link = filter_link
         self.object_link = object_link
         self.model_admin = model_admin
@@ -22,8 +21,9 @@ class ModelAdminFormatter(Formatter):
 
     def build_object_link(self, value):
         content_type = ContentType.objects.get_for_model(value.__class__)
-        url = u'{0}:{1}_{2}_change'.format(self.model_admin.admin_site.name,
-                content_type.app_label, content_type.model)
+        url = u'{0}:{1}_{2}_change'.format(
+            self.model_admin.admin_site.name, content_type.app_label, content_type.model
+        )
         try:
             url = reverse(url, args=(value.pk,))
         except NoReverseMatch:
@@ -36,7 +36,8 @@ class ModelAdminFormatter(Formatter):
             if self.filter_link:
                 content_type = ContentType.objects.get_for_model(value.__class__)
                 res = u'<a href="?objectdata__content_type={0}&objectdata__object_id={1}">{2}</a>'.format(
-                            content_type.id, value.pk, escape(force_text(value)))
+                    content_type.id, value.pk, escape(force_text(value))
+                )
             else:
                 res = escape(force_text(value))
             if self.object_link:
@@ -52,6 +53,7 @@ class ObjectDataInlineAdmin(admin.TabularInline):
     extra = 0
     max_num = 0
 
+
 class StringDataInlineAdmin(admin.TabularInline):
     model = StringData
     fields = ('tag', 'content')
@@ -59,31 +61,35 @@ class StringDataInlineAdmin(admin.TabularInline):
     extra = 0
     max_num = 0
 
+
 class JournalAdmin(admin.ModelAdmin):
     list_display = ('time', '_tag', 'user', 'ip', 'message_for_list')
     list_filter = ('tag',)
     fields = ('time', 'tag', 'user', 'ip', 'message_for_change')
     readonly_fields = fields
     inlines = (
-            ObjectDataInlineAdmin, 
-            StringDataInlineAdmin,
+        ObjectDataInlineAdmin,
+        StringDataInlineAdmin,
     )
     date_hierarchy = 'time'
-    search_fields = ('message','tag__name','time')
-    actions = [ export_as_csv ]
+    search_fields = ('message', 'tag__name', 'time')
+    actions = [export_as_csv]
 
     class Media:
         css = {
-                'all': ('journal/css/journal.css',),
+            'all': ('journal/css/journal.css',),
         }
 
     def queryset(self, request):
         '''Get as much data as possible using the fewest requests possible.'''
         qs = super(JournalAdmin, self).queryset(request)
-        qs = qs.select_related('tag', 'template') \
-               .prefetch_related('objectdata_set__content_type',
-                       'stringdata_set', 'objectdata_set__tag',
-                       'stringdata_set__tag', 'objectdata_set__content_object')
+        qs = qs.select_related('tag', 'template').prefetch_related(
+            'objectdata_set__content_type',
+            'stringdata_set',
+            'objectdata_set__tag',
+            'stringdata_set__tag',
+            'objectdata_set__content_object',
+        )
         return qs
 
     def lookup_allowed(self, key, *args, **kwargs):
@@ -91,28 +97,31 @@ class JournalAdmin(admin.ModelAdmin):
 
     def _tag(self, entry):
         name = entry.tag.name.replace(u'-', u'\u2011')
-        res = format_html('<a href="?tag__id__exact={0}">{1}</a>',
-                escape(entry.tag.id), escape(name))
+        res = format_html('<a href="?tag__id__exact={0}">{1}</a>', escape(entry.tag.id), escape(name))
         return res
+
     _tag.short_description = _('tag')
 
     def ip(self, entry):
         '''Search and return any associated stringdata whose tag is "ip"'''
         for stringdata in entry.stringdata_set.all():
             if stringdata.tag.name == 'ip':
-                return format_html('<a href="?stringdata__tag__id={tag_id}&' \
-                                   'stringdata__content={ip}">{ip}</a>',
-                        tag_id=stringdata.tag.id, ip=stringdata.content)
+                return format_html(
+                    '<a href="?stringdata__tag__id={tag_id}&' 'stringdata__content={ip}">{ip}</a>',
+                    tag_id=stringdata.tag.id,
+                    ip=stringdata.content,
+                )
         return _('None')
+
     ip.short_description = _('IP')
 
     def user(self, entry):
         '''Search and return any associated objectdata whose tag is "user"'''
         for objectdata in entry.objectdata_set.all():
             if objectdata.tag.name == 'user':
-                return format_html(self.object_filter_link(objectdata) + \
-                        self.object_link(objectdata))
+                return format_html(self.object_filter_link(objectdata) + self.object_link(objectdata))
         return _('None')
+
     user.short_description = _('User')
 
     def object_filter_link(self, objectdata):
@@ -120,19 +129,18 @@ class JournalAdmin(admin.ModelAdmin):
             caption = force_text(objectdata.content_object)
         else:
             caption = _(u'<deleted {content_type} {object_id}>').format(
-                    content_type=objectdata.content_type,
-                    object_id=objectdata.object_id)
+                content_type=objectdata.content_type, object_id=objectdata.object_id
+            )
         return u'<a href="?objectdata__content_type={0}&objectdata__object_id={1}">{2}</a>'.format(
-                    objectdata.content_type_id,
-                    objectdata.object_id,
-                    escape(caption))
+            objectdata.content_type_id, objectdata.object_id, escape(caption)
+        )
 
     def object_link(self, obj_data):
         if obj_data.content_object is None:
             return u''
-        url = u'{0}:{1}_{2}_change'.format(self.admin_site.name,
-                obj_data.content_type.app_label,
-                obj_data.content_type.model)
+        url = u'{0}:{1}_{2}_change'.format(
+            self.admin_site.name, obj_data.content_type.app_label, obj_data.content_type.model
+        )
         try:
             url = reverse(url, args=(obj_data.object_id,))
         except NoReverseMatch:
@@ -144,6 +152,7 @@ class JournalAdmin(admin.ModelAdmin):
         formatter = ModelAdminFormatter(model_admin=self, filter_link=False)
         message = formatter.format(escape(entry.template.content), **ctx)
         return format_html('<span>{}</span>', mark_safe(message))
+
     message_for_change.short_description = _('Message')
 
     def message_for_list(self, entry):
@@ -151,8 +160,10 @@ class JournalAdmin(admin.ModelAdmin):
         formatter = ModelAdminFormatter(model_admin=self)
         message = formatter.format(entry.template.content, **ctx)
         return format_html('<span>{}</span>', mark_safe(message))
+
     message_for_list.short_description = _('Message')
     message_for_list.admin_order_field = 'message'
 
+
 admin.site.register(Journal, JournalAdmin)
 admin.site.register(Tag)
diff --git a/django_journal/decorator.py b/django_journal/decorator.py
index 824227a..d108693 100644
--- a/django_journal/decorator.py
+++ b/django_journal/decorator.py
@@ -4,6 +4,7 @@ from django.db import transaction, DEFAULT_DB_ALIAS
 if hasattr(transaction, 'atomic'):
     atomic = transaction.atomic
 else:
+
     class Transaction(object):
         sid = None
 
@@ -41,8 +42,8 @@ else:
             def wrapper(*args, **kwargs):
                 with self.__class__(using=self.using):
                     return func(*args, **kwargs)
-            return wrapper
 
+            return wrapper
 
     def atomic(using=None):
         """
@@ -56,5 +57,3 @@ else:
         if callable(using):
             return Transaction(DEFAULT_DB_ALIAS)(using)
         return Transaction(using)
-
-
diff --git a/django_journal/journal.py b/django_journal/journal.py
index 69892a8..cc05c1b 100644
--- a/django_journal/journal.py
+++ b/django_journal/journal.py
@@ -11,32 +11,31 @@ from .models import Journal, Tag, Template
 
 
 def unicode_truncate(s, length, encoding='utf-8'):
-    '''Truncate an unicode string so that its UTF-8 encoding is less than
-       length.'''
+    """Truncate an unicode string so that its UTF-8 encoding is less than
+    length."""
     encoded = s.encode(encoding)[:length]
     return encoded.decode(encoding, 'ignore')
 
 
 @atomic
 def record(tag, template, using=None, **kwargs):
-    '''Record an event in the journal. The modification is done inside the
-       current transaction.
+    """Record an event in the journal. The modification is done inside the
+    current transaction.
 
-       tag:
-           a string identifier giving the type of the event
-       tpl:
-           a format string to describe the event
-       kwargs:
-           a mapping of object or data to interpolate in the format string
-    '''
+    tag:
+        a string identifier giving the type of the event
+    tpl:
+        a format string to describe the event
+    kwargs:
+        a mapping of object or data to interpolate in the format string
+    """
     template = force_text(template)
     tag = Tag.objects.using(using).get_cached(name=tag)
     template = Template.objects.using(using).get_cached(content=template)
     try:
         message = template.content.format(**kwargs)
     except (KeyError, IndexError) as e:
-        raise JournalException(
-                'Missing variable for the template message', template, e)
+        raise JournalException('Missing variable for the template message', template, e)
     try:
         logger = logging.getLogger('django.journal.%s' % tag)
         if tag.name == 'error' or tag.name.startswith('error-'):
@@ -49,17 +48,19 @@ def record(tag, template, using=None, **kwargs):
         try:
             logging.getLogger('django.journal').exception('Unable to log msg')
         except:
-            pass # we tried, really, we tried
-    journal = Journal.objects.using(using).create(tag=tag, template=template,
-            message=unicode_truncate(message, 128))
+            pass  # we tried, really, we tried
+    journal = Journal.objects.using(using).create(
+        tag=tag, template=template, message=unicode_truncate(message, 128)
+    )
     for name, value in kwargs.items():
         if value is None:
             continue
         tag = Tag.objects.using(using).get_cached(name=name)
         if isinstance(value, django.db.models.Model):
             journal.objectdata_set.create(
-                tag=tag, content_type=ContentType.objects.db_manager(using).get_for_model(value),
-                object_id=value.pk
+                tag=tag,
+                content_type=ContentType.objects.db_manager(using).get_for_model(value),
+                object_id=value.pk,
             )
         else:
             journal.stringdata_set.create(tag=tag, content=force_text(value))
@@ -67,13 +68,13 @@ def record(tag, template, using=None, **kwargs):
 
 
 def error_record(tag, tpl, **kwargs):
-    '''Records error events.
+    """Records error events.
 
-       You must use this function when logging error events. It uses another
-       database alias than the default one to be immune to transaction rollback
-       when logging in the middle of a transaction which is going to
-       rollback.
-    '''
+    You must use this function when logging error events. It uses another
+    database alias than the default one to be immune to transaction rollback
+    when logging in the middle of a transaction which is going to
+    rollback.
+    """
     if kwargs.get('using') is None:
         kwargs['using'] = getattr(settings, 'JOURNAL_DB_FOR_ERROR_ALIAS', 'default')
 
diff --git a/django_journal/managers.py b/django_journal/managers.py
index 10aea73..9f97c2e 100644
--- a/django_journal/managers.py
+++ b/django_journal/managers.py
@@ -27,34 +27,29 @@ class JournalQuerySet(QuerySet):
         '''Return Journal records linked to this object.'''
         content_type = ContentType.objects.get_for_model(obj)
         if tag is None:
-            return self.filter(objectdata__content_type=content_type,
-                    objectdata__object_id=obj.pk)
+            return self.filter(objectdata__content_type=content_type, objectdata__object_id=obj.pk)
         else:
             return self.filter(
-                    objectdata__tag__name=tag,
-                    objectdata__content_type=content_type,
-                    objectdata__object_id=obj.pk)
+                objectdata__tag__name=tag, objectdata__content_type=content_type, objectdata__object_id=obj.pk
+            )
 
     def for_objects(self, objects):
-        '''Return journal records linked to any of this objects.
+        """Return journal records linked to any of this objects.
 
-           All objects must have the same model.
-        '''
+        All objects must have the same model.
+        """
         if not objects:
             return self.none()
-        content_types = [ ContentType.objects.get_for_model(obj)
-                for obj in objects ]
+        content_types = [ContentType.objects.get_for_model(obj) for obj in objects]
         if len(set(content_types)) != 1:
             raise ValueError('objects must have of the same content type')
-        pks = [ obj.pk for obj in objects ]
-        return self.filter(
-                objectdata__content_type=content_types[0],
-                objectdata__object_id__in=pks)
+        pks = [obj.pk for obj in objects]
+        return self.filter(objectdata__content_type=content_types[0], objectdata__object_id__in=pks)
 
     def for_tag(self, tag):
-        '''Returns Journal records linked to this tag by their own tag or
-           the tag on their data records.
-        '''
+        """Returns Journal records linked to this tag by their own tag or
+        the tag on their data records.
+        """
         from . import models
 
         if not isinstance(tag, models.Tag):
@@ -64,17 +59,22 @@ class JournalQuerySet(QuerySet):
                 return self.none()
         # always remember: multiple join (OR in WHERE) produces duplicate
         # lines ! Use .distinct() for safety.
-        return self.filter(Q(tag=tag)|
-                Q(objectdata__tag=tag)|
-                Q(stringdata__tag=tag)) \
-                .distinct()
+        return self.filter(Q(tag=tag) | Q(objectdata__tag=tag) | Q(stringdata__tag=tag)).distinct()
 
 
 class JournalManager(Manager.from_queryset(JournalQuerySet)):
     def get_query_set(self):
-        return super(JournalManager, self).get_query_set() \
-               .prefetch_related('objectdata_set__content_type',
-                       'stringdata_set', 'objectdata_set__tag',
-                       'stringdata_set__tag', 'objectdata_set__content_object',
-                       'tag', 'template') \
-               .select_related('tag', 'template')
+        return (
+            super(JournalManager, self)
+            .get_query_set()
+            .prefetch_related(
+                'objectdata_set__content_type',
+                'stringdata_set',
+                'objectdata_set__tag',
+                'stringdata_set__tag',
+                'objectdata_set__content_object',
+                'tag',
+                'template',
+            )
+            .select_related('tag', 'template')
+        )
diff --git a/django_journal/middleware.py b/django_journal/middleware.py
index c3b8be0..34431a9 100644
--- a/django_journal/middleware.py
+++ b/django_journal/middleware.py
@@ -3,27 +3,30 @@ from django_journal import journal
 
 
 class JournalMiddleware(MiddlewareMixin):
-    '''Add record and error_record methods to the request object to log
-       current user and current REMOTE_ADRESS.
+    """Add record and error_record methods to the request object to log
+    current user and current REMOTE_ADRESS.
 
-       It must be setup after the auth middleware.
-    '''
+    It must be setup after the auth middleware.
+    """
 
     def process_request(self, request):
         user = getattr(request, 'user', None)
         ip = request.META.get('REMOTE_ADDR', None)
+
         def record(tag, template, using=None, **kwargs):
             if 'user' not in kwargs:
                 kwargs['user'] = user
             if 'ip' not in kwargs:
                 kwargs['ip'] = ip
-            journal.record(tag, template, using=using,**kwargs)
+            journal.record(tag, template, using=using, **kwargs)
+
         def error_record(tag, template, using=None, **kwargs):
             if 'user' not in kwargs:
                 kwargs['user'] = user
             if 'ip' not in kwargs:
                 kwargs['ip'] = ip
             journal.error_record(tag, template, using=using, **kwargs)
+
         request.record = record
         request.error_record = error_record
         return None
diff --git a/django_journal/migrations/0001_initial.py b/django_journal/migrations/0001_initial.py
index 8a5def2..cacfa01 100644
--- a/django_journal/migrations/0001_initial.py
+++ b/django_journal/migrations/0001_initial.py
@@ -15,7 +15,10 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Journal',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                (
+                    'id',
+                    models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
+                ),
                 ('time', models.DateTimeField(auto_now_add=True, verbose_name='time', db_index=True)),
                 ('message', models.CharField(max_length=128, verbose_name='message', db_index=True)),
             ],
@@ -28,10 +31,23 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='ObjectData',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                (
+                    'id',
+                    models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
+                ),
                 ('object_id', models.PositiveIntegerField(verbose_name='object id', db_index=True)),
-                ('content_type', models.ForeignKey(verbose_name='content type', to='contenttypes.ContentType', on_delete=models.CASCADE)),
-                ('journal', models.ForeignKey(verbose_name='journal entry', to='django_journal.Journal', on_delete=models.CASCADE)),
+                (
+                    'content_type',
+                    models.ForeignKey(
+                        verbose_name='content type', to='contenttypes.ContentType', on_delete=models.CASCADE
+                    ),
+                ),
+                (
+                    'journal',
+                    models.ForeignKey(
+                        verbose_name='journal entry', to='django_journal.Journal', on_delete=models.CASCADE
+                    ),
+                ),
             ],
             options={
                 'verbose_name': 'linked object',
@@ -40,9 +56,17 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='StringData',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                (
+                    'id',
+                    models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
+                ),
                 ('content', models.TextField(verbose_name='content')),
-                ('journal', models.ForeignKey(verbose_name='journal entry', to='django_journal.Journal', on_delete=models.CASCADE)),
+                (
+                    'journal',
+                    models.ForeignKey(
+                        verbose_name='journal entry', to='django_journal.Journal', on_delete=models.CASCADE
+                    ),
+                ),
             ],
             options={
                 'verbose_name': 'linked text string',
@@ -51,7 +75,10 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Tag',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                (
+                    'id',
+                    models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
+                ),
                 ('name', models.CharField(unique=True, max_length=32, verbose_name='name', db_index=True)),
             ],
             options={
@@ -62,7 +89,10 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Template',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                (
+                    'id',
+                    models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
+                ),
                 ('content', models.TextField(unique=True, verbose_name='content', db_index=True)),
             ],
             options={
@@ -82,12 +112,18 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='journal',
             name='tag',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, verbose_name='tag', to='django_journal.Tag'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, verbose_name='tag', to='django_journal.Tag'
+            ),
         ),
         migrations.AddField(
             model_name='journal',
             name='template',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, verbose_name='template', to='django_journal.Template'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT,
+                verbose_name='template',
+                to='django_journal.Template',
+            ),
         ),
         migrations.AlterUniqueTogether(
             name='stringdata',
diff --git a/django_journal/models.py b/django_journal/models.py
index 10840bf..bd33f27 100644
--- a/django_journal/models.py
+++ b/django_journal/models.py
@@ -10,14 +10,14 @@ from . import managers
 
 @python_2_unicode_compatible
 class Tag(models.Model):
-    '''Tag allows typing event and data linked to events.
+    """Tag allows typing event and data linked to events.
+
+    name:
+        the string identifier of the tag
+    """
 
-       name:
-           the string identifier of the tag
-    '''
     objects = managers.TagManager()
-    name = models.CharField(verbose_name=_('name'), max_length=32, unique=True,
-            db_index=True)
+    name = models.CharField(verbose_name=_('name'), max_length=32, unique=True, db_index=True)
 
     def __str__(self):
         return self.name
@@ -32,14 +32,14 @@ class Tag(models.Model):
 
 @python_2_unicode_compatible
 class Template(models.Model):
-    '''Template for formatting an event.
+    """Template for formatting an event.
+
+    ex.: Template(
+             content='{user1} gave group {group} to {user2}')
+    """
 
-       ex.: Template(
-                content='{user1} gave group {group} to {user2}')
-    '''
     objects = managers.TemplateManager()
-    content = models.TextField(verbose_name=_('content'), unique=True,
-            db_index=True)
+    content = models.TextField(verbose_name=_('content'), unique=True, db_index=True)
 
     def __str__(self):
         return self.content
@@ -53,26 +53,23 @@ class Template(models.Model):
 
 @python_2_unicode_compatible
 class Journal(models.Model):
-    '''One line of the journal.
+    """One line of the journal.
 
-       Each recorded event in the journal is a Journal instance.
+    Each recorded event in the journal is a Journal instance.
+
+    time - the time at which the event was recorded
+    tag - the tag giving the type of event
+    template - a format string to present the event
+    message - a simple string representation of the event, computed using
+    the template and associated datas.
+    """
 
-       time - the time at which the event was recorded
-       tag - the tag giving the type of event
-       template - a format string to present the event
-       message - a simple string representation of the event, computed using
-       the template and associated datas.
-    '''
     objects = managers.JournalManager()
 
-    time = models.DateTimeField(verbose_name=_('time'), auto_now_add=True,
-            db_index=True)
-    tag = models.ForeignKey(Tag, verbose_name=_('tag'),
-            on_delete=models.PROTECT)
-    template = models.ForeignKey(Template, verbose_name=_('template'),
-            on_delete=models.PROTECT)
-    message = models.CharField(verbose_name=_('message'), max_length=128,
-            db_index=True)
+    time = models.DateTimeField(verbose_name=_('time'), auto_now_add=True, db_index=True)
+    tag = models.ForeignKey(Tag, verbose_name=_('tag'), on_delete=models.PROTECT)
+    template = models.ForeignKey(Template, verbose_name=_('template'), on_delete=models.PROTECT)
+    message = models.CharField(verbose_name=_('message'), max_length=128, db_index=True)
 
     class Meta:
         ordering = ('-id',)
@@ -86,7 +83,8 @@ class Journal(models.Model):
                 ctx[data.tag.name] = data.content_object
             else:
                 ctx[data.tag.name] = u'<deleted {content_type} {object_id}>'.format(
-                        content_type=data.content_type, object_id=data.object_id)
+                    content_type=data.content_type, object_id=data.object_id
+                )
         for data in self.stringdata_set.all():
             ctx[data.tag.name] = data.content
         for text, field, format_spec, conversion in string.Formatter().parse(self.template.content):
@@ -98,9 +96,7 @@ class Journal(models.Model):
         return ctx
 
     def add_object_tag(self, tag_name, obj):
-        ObjectData(journal=self,
-                tag=Tag.objects.get_cached(name=tag_name),
-                content_object=obj).save()
+        ObjectData(journal=self, tag=Tag.objects.get_cached(name=tag_name), content_object=obj).save()
 
     def __str__(self):
         ctx = self.message_context()
@@ -108,20 +104,21 @@ class Journal(models.Model):
 
     def __repr__(self):
         return '<Journal pk:{0} tag:{1} message:{2}>'.format(
-                self.pk, unicode(self.tag).encode('utf-8'),
-                unicode(self.message).encode('utf-8'))
+            self.pk, unicode(self.tag).encode('utf-8'), unicode(self.message).encode('utf-8')
+        )
 
 
 class StringData(models.Model):
-    '''String data associated to a recorded event.
-
-       journal:
-           the recorded event
-       tag:
-           the identifier for this data
-       content:
-           the string value of the data
-    '''
+    """String data associated to a recorded event.
+
+    journal:
+        the recorded event
+    tag:
+        the identifier for this data
+    content:
+        the string value of the data
+    """
+
     journal = models.ForeignKey(Journal, verbose_name=_('journal entry'), on_delete=models.CASCADE)
     tag = models.ForeignKey(Tag, verbose_name=_('tag'), on_delete=models.CASCADE)
     content = models.TextField(verbose_name=_('content'))
@@ -133,23 +130,23 @@ class StringData(models.Model):
 
 @python_2_unicode_compatible
 class ObjectData(models.Model):
-    '''Object data associated with a recorded event.
-
-       journal:
-           the recorded event
-       tag:
-           the identifier for this data
-       content_object:
-           the object value of the data
-    '''
+    """Object data associated with a recorded event.
+
+    journal:
+        the recorded event
+    tag:
+        the identifier for this data
+    content_object:
+        the object value of the data
+    """
+
     journal = models.ForeignKey(Journal, verbose_name=_('journal entry'), on_delete=models.CASCADE)
     tag = models.ForeignKey(Tag, verbose_name=_('tag'), on_delete=models.CASCADE)
-    content_type = models.ForeignKey('contenttypes.ContentType', on_delete=models.CASCADE,
-            verbose_name=_('content type'))
-    object_id = models.PositiveIntegerField(db_index=True,
-            verbose_name=_('object id'))
-    content_object = GenericForeignKey('content_type',
-            'object_id')
+    content_type = models.ForeignKey(
+        'contenttypes.ContentType', on_delete=models.CASCADE, verbose_name=_('content type')
+    )
+    object_id = models.PositiveIntegerField(db_index=True, verbose_name=_('object id'))
+    content_object = GenericForeignKey('content_type', 'object_id')
 
     class Meta:
         unique_together = (('journal', 'tag'),)
diff --git a/setup.py b/setup.py
index 6528369..d903f29 100755
--- a/setup.py
+++ b/setup.py
@@ -22,6 +22,7 @@ class test(Command):
 
     def run(self):
         import os
+
         try:
             from django.core.management import call_command
         except ImportError:
@@ -45,6 +46,7 @@ class compile_translations(Command):
         try:
             os.environ.pop('DJANGO_SETTINGS_MODULE', None)
             from django.core.management import call_command
+
             os.chdir(os.path.realpath('django_journal'))
             call_command('compilemessages')
         except ImportError:
@@ -80,16 +82,18 @@ class eo_sdist(sdist):
 
 
 def get_version():
-    '''Use the VERSION, if absent generates a version with git describe, if not
-       tag exists, take 0.0- and add the length of the commit log.
-    '''
+    """Use the VERSION, if absent generates a version with git describe, if not
+    tag exists, take 0.0- and add the length of the commit log.
+    """
     if os.path.exists('VERSION'):
         with open('VERSION', 'r') as v:
             return v.read()
     if os.path.exists('.git'):
         p = subprocess.Popen(
             ['git', 'describe', '--dirty=.dirty', '--match=v*'],
-            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+        )
         result = p.communicate()[0]
         if p.returncode == 0:
             result = result.decode('ascii').strip()[1:]  # strip spaces/newlines and initial v
@@ -100,30 +104,27 @@ def get_version():
                 version = result
             return version
         else:
-            return '0.0.post%s' % len(
-                    subprocess.check_output(
-                            ['git', 'rev-list', 'HEAD']).splitlines())
+            return '0.0.post%s' % len(subprocess.check_output(['git', 'rev-list', 'HEAD']).splitlines())
     return '0.0'
 
 
-setup(name='django-journal',
-      version=get_version(),
-      license='AGPLv3',
-      description='Keep a structured -- i.e. not just log strings -- journal'
-                  ' of events in your applications',
-      url='http://dev.entrouvert.org/projects/django-journal/',
-      download_url='http://repos.entrouvert.org/django-journal.git/',
-      author="Entr'ouvert",
-      author_email="info@entrouvert.com",
-      packages=find_packages(os.path.dirname(__file__) or '.'),
-      include_package_data=True,
-      cmdclass={
-          'build': build,
-          'install_lib': install_lib,
-          'compile_translations': compile_translations,
-          'sdist': eo_sdist,
-          'test': test
-      },
-      install_requires=[
-          'django >= 1.11,<2.3'
-      ])
+setup(
+    name='django-journal',
+    version=get_version(),
+    license='AGPLv3',
+    description='Keep a structured -- i.e. not just log strings -- journal' ' of events in your applications',
+    url='http://dev.entrouvert.org/projects/django-journal/',
+    download_url='http://repos.entrouvert.org/django-journal.git/',
+    author="Entr'ouvert",
+    author_email="info@entrouvert.com",
+    packages=find_packages(os.path.dirname(__file__) or '.'),
+    include_package_data=True,
+    cmdclass={
+        'build': build,
+        'install_lib': install_lib,
+        'compile_translations': compile_translations,
+        'sdist': eo_sdist,
+        'test': test,
+    },
+    install_requires=['django >= 1.11,<2.3'],
+)
diff --git a/test_settings.py b/test_settings.py
index f0902ed..b1ca36e 100644
--- a/test_settings.py
+++ b/test_settings.py
@@ -1,16 +1,12 @@
 INSTALLED_APPS = (
-    'django_journal', 'django.contrib.contenttypes', 'django.contrib.auth',
-    'django.contrib.sessions'
+    'django_journal',
+    'django.contrib.contenttypes',
+    'django.contrib.auth',
+    'django.contrib.sessions',
 )
 DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.postgresql_psycopg2',
-        'NAME': '_test'
-    },
-    'error': {
-        'ENGINE': 'django.db.backends.postgresql_psycopg2',
-        'NAME': '_test'
-    }
+    'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': '_test'},
+    'error': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': '_test'},
 }
 
 SECRET_KEY = "django_tests_secret_key"
diff --git a/tests/test_main.py b/tests/test_main.py
index 766b4cd..85d9c67 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -15,17 +15,19 @@ class JournalTestCase(TestCase):
         self.groups = []
         with transaction.atomic():
             for i in range(20):
-                self.users.append(
-                        User.objects.create(username='user%s' % i))
+                self.users.append(User.objects.create(username='user%s' % i))
             for i in range(20):
-                self.groups.append(
-                        Group.objects.create(name='group%s' % i))
+                self.groups.append(Group.objects.create(name='group%s' % i))
             for i in range(20):
                 record('login', '{user} logged in', user=self.users[i])
             for i in range(20):
-                record('group-changed', '{user1} gave group {group} to {user2}',
-                        user1=self.users[i], group=self.groups[i], 
-                        user2=self.users[(i+1) % 20])
+                record(
+                    'group-changed',
+                    '{user1} gave group {group} to {user2}',
+                    user1=self.users[i],
+                    group=self.groups[i],
+                    user2=self.users[(i + 1) % 20],
+                )
             for i in range(20):
                 record('logout', '{user} logged out', user=self.users[i])
 
@@ -35,8 +37,9 @@ class JournalTestCase(TestCase):
 
     def test_groups(self):
         for i, event in zip(range(40), Journal.objects.for_tag('group-changed').order_by('id')):
-            self.assertEqual(force_text(event),
-                    'user{0} gave group group{0} to user{1}'.format(i, (i+1)%20))
+            self.assertEqual(
+                force_text(event), 'user{0} gave group group{0} to user{1}'.format(i, (i + 1) % 20)
+            )
 
     def test_logout(self):
         for i, event in zip(range(20), Journal.objects.for_tag('logout').order_by('id')):
@@ -45,7 +48,22 @@ class JournalTestCase(TestCase):
     def test_export_as_csv(self):
         qs = Journal.objects.all()
         l = list(export_as_csv_generator(qs))
-        self.assertEquals(set(l[0]), set(['time', 'tag', 'message', 'group', 'group__id', 'user', 'user__id', 'user1', 'user1__id', 'user2', 'user2__id']))
+        self.assertEquals(
+            set(l[0]),
+            {
+                'time',
+                'tag',
+                'message',
+                'group',
+                'group__id',
+                'user',
+                'user__id',
+                'user1',
+                'user1__id',
+                'user2',
+                'user2__id',
+            },
+        )
         l = list(export_as_csv_generator(qs[:5]))
         self.assertEquals(set(l[0]), set(['time', 'tag', 'message', 'user', 'user__id']))
         for user in self.users:
-- 
2.32.0

