diff --git a/docs/reference/pages/model_recipes.rst b/docs/reference/pages/model_recipes.rst index bf199f2287..b8ddd63a42 100644 --- a/docs/reference/pages/model_recipes.rst +++ b/docs/reference/pages/model_recipes.rst @@ -155,11 +155,11 @@ Using an example from the Wagtail demo site, here's what the tag model and the r from modelcluster.fields import ParentalKey from modelcluster.contrib.taggit import ClusterTaggableManager - from taggit.models import Tag, TaggedItemBase - ... + from taggit.models import TaggedItemBase + class BlogPageTag(TaggedItemBase): content_object = ParentalKey('demo.BlogPage', related_name='tagged_items') - ... + class BlogPage(Page): ... tags = ClusterTaggableManager(through=BlogPageTag, blank=True) diff --git a/docs/topics/snippets.rst b/docs/topics/snippets.rst index 8e4defe79a..ddeb24ac31 100644 --- a/docs/topics/snippets.rst +++ b/docs/topics/snippets.rst @@ -197,3 +197,30 @@ If a snippet model inherits from ``wagtail.wagtailsearch.index.Indexed``, as des search_fields = [ index.SearchField('text', partial_match=True), ] + + +Tagging snippets +---------------- + +Adding tags to snippets is very similar to adding tags to pages. The only difference is that :class:`taggit.manager.TaggableManager` should be used in the place of :class:`~modelcluster.contrib.taggit.ClusterTaggableManager`. + +.. code-block:: python + + from modelcluster.fields import ParentalKey + from taggit.models import TaggedItemBase + from taggit.managers import TaggableManager + + class AdvertTag(TaggedItemBase): + content_object = ParentalKey('demo.Advert', related_name='tagged_items') + + @register_snippet + class Advert(models.Model): + ... + tags = TaggableManager(through=BlogPageTag, blank=True) + + panels = [ + ... + FieldPanel('tags'), + ] + +The :ref:`documentation on tagging pages ` has more information on how to use tags in views. diff --git a/wagtail/tests/testapp/migrations/0007_auto_20150820_0419.py b/wagtail/tests/testapp/migrations/0007_auto_20150820_0419.py new file mode 100644 index 0000000000..c843b42dc9 --- /dev/null +++ b/wagtail/tests/testapp/migrations/0007_auto_20150820_0419.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import taggit.managers +import modelcluster.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('taggit', '0001_initial'), + ('tests', '0006_image_file_size'), + ] + + operations = [ + migrations.CreateModel( + name='AdvertTag', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('content_object', modelcluster.fields.ParentalKey(related_name='tagged_items', to='tests.Advert')), + ('tag', models.ForeignKey(related_name='tests_adverttag_items', to='taggit.Tag')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='advert', + name='tags', + field=taggit.managers.TaggableManager(to='taggit.Tag', through='tests.AdvertTag', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags'), + ), + ] diff --git a/wagtail/tests/testapp/models.py b/wagtail/tests/testapp/models.py index 76e38fefdd..c2334dca21 100644 --- a/wagtail/tests/testapp/models.py +++ b/wagtail/tests/testapp/models.py @@ -5,6 +5,7 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.utils.encoding import python_2_unicode_compatible from taggit.models import TaggedItemBase +from taggit.managers import TaggableManager from modelcluster.fields import ParentalKey from modelcluster.contrib.taggit import ClusterTaggableManager @@ -313,14 +314,22 @@ class AdvertPlacement(models.Model): advert = models.ForeignKey('tests.Advert', related_name='+') colour = models.CharField(max_length=255) + +class AdvertTag(TaggedItemBase): + content_object = ParentalKey('Advert', related_name='tagged_items') + + @python_2_unicode_compatible class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) + tags = TaggableManager(through=AdvertTag, blank=True) + panels = [ FieldPanel('url'), FieldPanel('text'), + FieldPanel('tags'), ] def __str__(self): diff --git a/wagtail/wagtailsnippets/tests.py b/wagtail/wagtailsnippets/tests.py index 6625ce2955..f551d12e8a 100644 --- a/wagtail/wagtailsnippets/tests.py +++ b/wagtail/wagtailsnippets/tests.py @@ -5,6 +5,8 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from django.core.exceptions import ImproperlyConfigured +from taggit.models import Tag + from wagtail.tests.utils import WagtailTestUtils from wagtail.tests.testapp.models import Advert, SnippetChooserModel from wagtail.tests.snippets.models import AlphaSnippet, ZuluSnippet, RegisterDecorator, RegisterFunction, SearchableSnippet @@ -142,6 +144,20 @@ class TestSnippetCreateView(TestCase, WagtailTestUtils): self.assertEqual(snippets.count(), 1) self.assertEqual(snippets.first().url, 'http://www.example.com/') + def test_create_with_tags(self): + tags = ['hello', 'world'] + response = self.post(post_data={'text': 'test_advert', + 'url': 'http://example.com/', + 'tags': ', '.join(tags)}) + + self.assertRedirects(response, reverse('wagtailsnippets:list', + args=('tests', 'advert'))) + + snippet = Advert.objects.get(text='test_advert') + self.assertEqual( + list(snippet.tags.order_by('name')), + list(Tag.objects.order_by('name').filter(name__in=tags))) + class TestSnippetEditView(TestCase, WagtailTestUtils): fixtures = ['test.json'] @@ -187,6 +203,20 @@ class TestSnippetEditView(TestCase, WagtailTestUtils): self.assertEqual(snippets.count(), 1) self.assertEqual(snippets.first().url, 'http://www.example.com/edited') + def test_edit_with_tags(self): + tags = ['hello', 'world'] + response = self.post(post_data={'text': 'edited_test_advert', + 'url': 'http://www.example.com/edited', + 'tags': ', '.join(tags)}) + + self.assertRedirects(response, reverse('wagtailsnippets:list', + args=('tests', 'advert'))) + + snippet = Advert.objects.get(text='edited_test_advert') + self.assertEqual( + list(snippet.tags.order_by('name')), + list(Tag.objects.order_by('name').filter(name__in=tags))) + class TestSnippetDelete(TestCase, WagtailTestUtils): fixtures = ['test.json']