diff --git a/bookmarks/migrations/0002_auto_20190629_2303.py b/bookmarks/migrations/0002_auto_20190629_2303.py
new file mode 100644
index 0000000..9d9a2e6
--- /dev/null
+++ b/bookmarks/migrations/0002_auto_20190629_2303.py
@@ -0,0 +1,30 @@
+# Generated by Django 2.2.2 on 2019-06-29 23:03
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('bookmarks', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Tag',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=64)),
+ ('date_added', models.DateTimeField()),
+ ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.AddField(
+ model_name='bookmark',
+ name='tags',
+ field=models.ManyToManyField(to='bookmarks.Tag'),
+ ),
+ ]
diff --git a/bookmarks/models.py b/bookmarks/models.py
index 748c72e..5b1124f 100644
--- a/bookmarks/models.py
+++ b/bookmarks/models.py
@@ -3,6 +3,12 @@ from django.contrib.auth import get_user_model
from django.db import models
+class Tag(models.Model):
+ name = models.CharField(max_length=64)
+ date_added = models.DateTimeField()
+ owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
+
+
class Bookmark(models.Model):
url = models.URLField()
title = models.CharField(max_length=512)
@@ -14,6 +20,7 @@ class Bookmark(models.Model):
date_modified = models.DateTimeField()
date_accessed = models.DateTimeField(blank=True, null=True)
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
+ tags = models.ManyToManyField(Tag)
@property
def resolved_title(self):
diff --git a/bookmarks/queries.py b/bookmarks/queries.py
index 54eccf3..b79274a 100644
--- a/bookmarks/queries.py
+++ b/bookmarks/queries.py
@@ -1,11 +1,27 @@
from django.contrib.auth.models import User
-from django.db.models import Q
+from django.db.models import Q, Count, Aggregate, CharField
from bookmarks.models import Bookmark
+class Concat(Aggregate):
+ function = 'GROUP_CONCAT'
+ template = '%(function)s(%(distinct)s%(expressions)s)'
+
+ def __init__(self, expression, distinct=False, **extra):
+ super(Concat, self).__init__(
+ expression,
+ distinct='DISTINCT ' if distinct else '',
+ output_field=CharField(),
+ **extra)
+
+
def query_bookmarks(user: User, query_string: str):
- query_set = Bookmark.objects
+
+ # Add aggregated tag info to bookmark instances
+ query_set = Bookmark.objects \
+ .annotate(tags_count=Count('tags')) \
+ .annotate(tags_string=Concat('tags__name'))
# Sanitize query params
if not query_string:
diff --git a/bookmarks/services/importer.py b/bookmarks/services/importer.py
index d39d9b6..6fa5469 100644
--- a/bookmarks/services/importer.py
+++ b/bookmarks/services/importer.py
@@ -1,9 +1,11 @@
from datetime import datetime
-from bs4 import BeautifulSoup, Tag
+import bs4
+from bs4 import BeautifulSoup
from django.contrib.auth.models import User
+from django.utils import timezone
-from bookmarks.models import Bookmark
+from bookmarks.models import Bookmark, Tag
def import_netscape_html(html: str, user: User):
@@ -15,7 +17,7 @@ def import_netscape_html(html: str, user: User):
_import_bookmark_tag(bookmark_tag, user)
-def _import_bookmark_tag(bookmark_tag: Tag, user: User):
+def _import_bookmark_tag(bookmark_tag: bs4.Tag, user: User):
link_tag = bookmark_tag.a
if link_tag is None:
@@ -34,9 +36,27 @@ def _import_bookmark_tag(bookmark_tag: Tag, user: User):
bookmark.save()
+ # Set tags
+ tag_string = link_tag['tags']
+ tag_names = tag_string.strip().split(',')
+
+ tags = [_get_or_create_tag(tag_name, user) for tag_name in tag_names]
+ bookmark.tags.set(tags)
+ bookmark.save()
+
def _get_or_create_bookmark(url: str, user: User):
try:
return Bookmark.objects.get(url=url, owner=user)
except Bookmark.DoesNotExist:
return Bookmark()
+
+
+def _get_or_create_tag(name: str, user: User):
+ try:
+ return Tag.objects.get(name=name, owner=user)
+ except Tag.DoesNotExist:
+ tag = Tag(name=name, owner=user)
+ tag.date_added = timezone.now()
+ tag.save()
+ return tag
diff --git a/bookmarks/templates/bookmarks/layout.html b/bookmarks/templates/bookmarks/layout.html
index 04c028e..9f9c28c 100644
--- a/bookmarks/templates/bookmarks/layout.html
+++ b/bookmarks/templates/bookmarks/layout.html
@@ -15,7 +15,7 @@
- linkdings
+ linkding
diff --git a/siteroot/settings.py b/siteroot/settings.py
index 3c47354..5e9011c 100644
--- a/siteroot/settings.py
+++ b/siteroot/settings.py
@@ -130,3 +130,25 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'bookmarks', 'styles'),
]
+# Logging with SQL statements
+LOGGING = {
+ 'version': 1,
+ 'filters': {
+ 'require_debug_true': {
+ '()': 'django.utils.log.RequireDebugTrue',
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'level': 'DEBUG',
+ 'filters': ['require_debug_true'],
+ 'class': 'logging.StreamHandler',
+ }
+ },
+ 'loggers': {
+ 'django.db.backends': {
+ 'level': 'DEBUG',
+ 'handlers': ['console'],
+ }
+ }
+}