kopia lustrzana https://github.com/wagtail/wagtail
Merge branch 'bug/tagged-snippets' of https://github.com/takeflight/wagtail into takeflight-bug/tagged-snippets
Conflicts: docs/topics/snippets.rstpull/1663/head
commit
e60e57016e
|
@ -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.fields import ParentalKey
|
||||||
from modelcluster.contrib.taggit import ClusterTaggableManager
|
from modelcluster.contrib.taggit import ClusterTaggableManager
|
||||||
from taggit.models import Tag, TaggedItemBase
|
from taggit.models import TaggedItemBase
|
||||||
...
|
|
||||||
class BlogPageTag(TaggedItemBase):
|
class BlogPageTag(TaggedItemBase):
|
||||||
content_object = ParentalKey('demo.BlogPage', related_name='tagged_items')
|
content_object = ParentalKey('demo.BlogPage', related_name='tagged_items')
|
||||||
...
|
|
||||||
class BlogPage(Page):
|
class BlogPage(Page):
|
||||||
...
|
...
|
||||||
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
|
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
|
||||||
|
|
|
@ -197,3 +197,30 @@ If a snippet model inherits from ``wagtail.wagtailsearch.index.Indexed``, as des
|
||||||
search_fields = [
|
search_fields = [
|
||||||
index.SearchField('text', partial_match=True),
|
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 <tagging>` has more information on how to use tags in views.
|
||||||
|
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -5,6 +5,7 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
from taggit.models import TaggedItemBase
|
from taggit.models import TaggedItemBase
|
||||||
|
from taggit.managers import TaggableManager
|
||||||
|
|
||||||
from modelcluster.fields import ParentalKey
|
from modelcluster.fields import ParentalKey
|
||||||
from modelcluster.contrib.taggit import ClusterTaggableManager
|
from modelcluster.contrib.taggit import ClusterTaggableManager
|
||||||
|
@ -313,14 +314,22 @@ class AdvertPlacement(models.Model):
|
||||||
advert = models.ForeignKey('tests.Advert', related_name='+')
|
advert = models.ForeignKey('tests.Advert', related_name='+')
|
||||||
colour = models.CharField(max_length=255)
|
colour = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
|
||||||
|
class AdvertTag(TaggedItemBase):
|
||||||
|
content_object = ParentalKey('Advert', related_name='tagged_items')
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Advert(models.Model):
|
class Advert(models.Model):
|
||||||
url = models.URLField(null=True, blank=True)
|
url = models.URLField(null=True, blank=True)
|
||||||
text = models.CharField(max_length=255)
|
text = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
tags = TaggableManager(through=AdvertTag, blank=True)
|
||||||
|
|
||||||
panels = [
|
panels = [
|
||||||
FieldPanel('url'),
|
FieldPanel('url'),
|
||||||
FieldPanel('text'),
|
FieldPanel('text'),
|
||||||
|
FieldPanel('tags'),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -5,6 +5,8 @@ from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
|
from taggit.models import Tag
|
||||||
|
|
||||||
from wagtail.tests.utils import WagtailTestUtils
|
from wagtail.tests.utils import WagtailTestUtils
|
||||||
from wagtail.tests.testapp.models import Advert, SnippetChooserModel
|
from wagtail.tests.testapp.models import Advert, SnippetChooserModel
|
||||||
from wagtail.tests.snippets.models import AlphaSnippet, ZuluSnippet, RegisterDecorator, RegisterFunction, SearchableSnippet
|
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.count(), 1)
|
||||||
self.assertEqual(snippets.first().url, 'http://www.example.com/')
|
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):
|
class TestSnippetEditView(TestCase, WagtailTestUtils):
|
||||||
fixtures = ['test.json']
|
fixtures = ['test.json']
|
||||||
|
@ -187,6 +203,20 @@ class TestSnippetEditView(TestCase, WagtailTestUtils):
|
||||||
self.assertEqual(snippets.count(), 1)
|
self.assertEqual(snippets.count(), 1)
|
||||||
self.assertEqual(snippets.first().url, 'http://www.example.com/edited')
|
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):
|
class TestSnippetDelete(TestCase, WagtailTestUtils):
|
||||||
fixtures = ['test.json']
|
fixtures = ['test.json']
|
||||||
|
|
Ładowanie…
Reference in New Issue