Commit 3ef47c09 authored by okhin's avatar okhin 🚴

Writing a custom tag splitter|joiner makes our life easier. And tags merging is now working.

parent e12ebd45
......@@ -33,7 +33,8 @@ class ArticleSerializer(TaggitSerializer, serializers.ModelSerializer):
#: List of short tags to describe the article (eg. "Privacy", "Copyright")
tags = TagListSerializerField(help_text="""
List of short tags to describe the article (eg."Privacy", "Copyright").
It must be a valid JSON list of tags.
It must be a valid JSON list of tags. The tags are case insensitive and
stored in lowercase (so Copyright === copyright).
For instance ["Privacy", "Copyright"}]
""", required=False)
......
from django import forms
from django.contrib.auth.models import Group
class TagMultipleChoiceField(forms.ModelMultipleChoiceField):
def prepare_value(self, value):
if hasattr(value, 'tag_id'):
return value.tag_id
elif hasattr(value, '__iter__') and not isinstance(value, str) and not hasattr(value, '_meta'):
return [self.prepare_value(v) for v in value]
else:
return super(TagMultipleChoiceField, self).prepare_value(value)
def clean(self, value):
value = self.to_python(value)
self.validate(value)
self.run_validators(value)
return value
class SignupForm(forms.Form):
def signup(self, request, user):
group = Group.objects.get(name='padawan')
......
......@@ -238,7 +238,7 @@ class Article(models.Model):
# Let's add the tags
if tags:
article.tags.set(*tags)
article.tags.add(*tags)
article.save()
try:
r = requests.get(url, timeout=0.5)
......@@ -251,6 +251,7 @@ class Article(models.Model):
article.url = url
article.save()
article.refresh_from_db()
return article
# Content extraction
......
......@@ -41,9 +41,14 @@ class TestArticle(TestCase):
assert article.status == 'NEW'
assert article.score == 1
article2 = Article.add_new_url(url='https://www.example.org/article')
article2 = Article.add_new_url(url='https://www.example.org/article',
tags=["Tag 1", "Tag 2"])
assert article2.status == 'NEW'
assert article2.score == 2
assert set(article2.tags.names()) == {"Tag 1", "Tag 2"}
article3 = Article.add_new_url(url='https://www.example.org/article',
tags=["Merged Tag"])
def test_flags(self):
assert not self.article.archive
......@@ -205,11 +210,13 @@ class TestArticleViews(TestCase):
a = {'title': 'Zog Zog',
'status': 'NEW',
'lang': 'FR',
'url': 'https://www.example.org/'}
'url': 'https://www.example.org/',
'tags': ["Merged Tag"]}
r = self.client.post('/rp/article/edit/{}/'.format(pk), a)
a = Article.objects.get(pk=pk)
assert r.status_code == 302 # We're redirecting to the view or preview of the article
assert a.title == 'Zog Zog'
assert set(a.tags.names()) == {"merged tag"}
class TestArticleApi(TestCase):
......
......@@ -34,3 +34,21 @@ def cleanup_url(url_path, default_scheme="http"):
u.scheme = default_scheme
return u.utf8
def tag_comma_splitter(tag_string):
"""
According to https://django-taggit.readthedocs.io/en/latest/custom_tagging.html,
this needs to be used by taggit using the settings TAGGIT_TAGS_FROM_STRING.
Our tags will be case insensitive.
"""
return [t.strip().lower() for t in tag_string.split(',') if t.strip()]
def tag_comma_joiner(tag_list):
"""
According to https://django-taggit.readthedocs.io/en/latest/custom_tagging.html,
this needs to be used by taggit using the settings TAGGIT_STRING_FROM_TAGS.
Our tags will be case insensitive.
"""
return ', '.join([t.name for t in tag_list])
......@@ -16,7 +16,6 @@ from crispy_forms.layout import Layout, Field, Div, HTML
from crispy_forms.bootstrap import AppendedText
from taggit.models import Tag
from rp.forms import TagMultipleChoiceField
from rp.models import Article
......@@ -169,7 +168,9 @@ class ArticleEdit(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
self.success_url = reverse("rp:article-view", args=[self.object.id])
elif "publish" in self.request.POST:
self.object.publish()
self.object.save()
form.save_m2m()
return HttpResponseRedirect(self.get_success_url())
......@@ -180,10 +181,6 @@ class ArticleEdit(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
form.helper = FormHelper()
form.helper.form_tag = False
# Change the layout of the tags field
form.fields["tags"] = TagMultipleChoiceField(
queryset=Tag.objects.all(), required=False)
left_layout = Div(
Div(
Field('title', wrapper_class='col-sm-10'),
......
......@@ -49,4 +49,9 @@ INSTALLED_APPS = DJANGO_APPS + CONTRIB_APPS + PROJECT_APPS
# Use username for upvote instead of user object
UND_USE_USERNAME = True
# Let's use a bootstrap4 template for crispy
CRISPY_TEMPLATE_PACK = "bootstrap4"
# We're using some dumber string parsing functions in taggit
TAGGIT_TAGS_FROM_STRING = 'rp.utils.tag_comma_splitter'
TAGGIT_STRING_FROM_TAGS = 'rp.utils.tag_comma_joiner'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment