diff --git a/bookmarks/services/tags.py b/bookmarks/services/tags.py index 3c13f9e..d79a7fe 100644 --- a/bookmarks/services/tags.py +++ b/bookmarks/services/tags.py @@ -1,3 +1,4 @@ +import logging import operator from typing import List @@ -7,6 +8,8 @@ from django.utils import timezone from bookmarks.models import Tag from bookmarks.utils import unique +logger = logging.getLogger(__name__) + def get_or_create_tags(tag_names: List[str], user: User): tags = [get_or_create_tag(tag_name, user) for tag_name in tag_names] @@ -21,3 +24,14 @@ def get_or_create_tag(name: str, user: User): tag.date_added = timezone.now() tag.save() return tag + except Tag.MultipleObjectsReturned: + # Legacy databases might contain duplicate tags with different capitalization + first_tag = Tag.objects.filter(name__iexact=name, owner=user).first() + message = ( + "Found multiple tags for the name '{0}' with different capitalization. " + "Using the first tag with the name '{1}'. " + "Since v.1.2 tags work case-insensitive, which means duplicates of the same name are not allowed anymore. " + "To solve this error remove the duplicate tag in admin." + ).format(name, first_tag.name) + logger.error(message) + return first_tag diff --git a/bookmarks/tests/test_tags_service.py b/bookmarks/tests/test_tags_service.py index 297385d..038df2c 100644 --- a/bookmarks/tests/test_tags_service.py +++ b/bookmarks/tests/test_tags_service.py @@ -42,6 +42,13 @@ class TagTestCase(TestCase): self.assertEqual(len(tags), 1) self.assertEqual(first_tag.id, second_tag.id) + def test_get_or_create_tag_should_handle_legacy_dbs_with_existing_duplicates(self): + Tag.objects.create(name='book', date_added=timezone.now(), owner=self.user) + Tag.objects.create(name='Book', date_added=timezone.now(), owner=self.user) + first_tag = get_or_create_tag('Book', self.user) + + self.assertEqual(first_tag.id, first_tag.id) + def test_get_or_create_tags_should_return_tags(self): books_tag = get_or_create_tag('Book', self.user) movies_tag = get_or_create_tag('Movie', self.user) diff --git a/siteroot/settings/dev.py b/siteroot/settings/dev.py index 5aed862..28f50e1 100644 --- a/siteroot/settings/dev.py +++ b/siteroot/settings/dev.py @@ -12,21 +12,25 @@ DEBUG = True SASS_PROCESSOR_ENABLED = True # Enable debug logging -# Logging with SQL statements LOGGING = { 'version': 1, - 'filters': { - 'require_debug_true': { - '()': 'django.utils.log.RequireDebugTrue', - } + 'disable_existing_loggers': False, + 'formatters': { + 'simple': { + 'format': '{levelname} {message}', + 'style': '{', + }, }, 'handlers': { 'console': { - 'level': 'DEBUG', - 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', + 'formatter': 'simple' } }, + 'root': { + 'handlers': ['console'], + 'level': 'WARNING', + }, 'loggers': { 'django.db.backends': { 'level': 'ERROR', # Set to DEBUG to log all SQL calls