pep8 fixes

Conflicts:
	wagtail/wagtailforms/models.py
	wagtail/wagtailimages/models.py
	wagtail/wagtailredirects/models.py
	wagtail/wagtailsnippets/edit_handlers.py
	wagtail/wagtailsnippets/tests.py
	wagtail/wagtailsnippets/views/snippets.py
	wagtail/wagtailsnippets/wagtail_hooks.py
	wagtail/wagtailusers/migrations/0001_initial.py
	wagtail/wagtailusers/migrations/0002_add_verbose_name_on_userprofile.py
	wagtail/wagtailusers/tests.py
	wagtail/wagtailusers/views/users.py
	wagtail/wagtailusers/wagtail_hooks.py
This commit is contained in:
c16192 2015-12-08 13:22:08 +00:00 committed by Matt Westcott
parent 0ce27f2f3d
commit 4433d4f3c0
31 changed files with 426 additions and 134 deletions

View file

@ -85,6 +85,7 @@ Contributors
* LKozlowski
* Matthew Downey
* Maris Serzans
* Shu Ishida
Translators

View file

@ -212,7 +212,10 @@ class AbstractEmailForm(AbstractForm):
A Form Page that sends email. Pages implementing a form to be send to an email should inherit from it
"""
to_address = models.CharField(verbose_name=_('to address'), max_length=255, blank=True, help_text=_("Optional - form submissions will be emailed to this address"))
to_address = models.CharField(
verbose_name=_('to address'), max_length=255, blank=True,
help_text=_("Optional - form submissions will be emailed to this address")
)
from_address = models.CharField(verbose_name=_('from address'), max_length=255, blank=True)
subject = models.CharField(verbose_name=_('subject'), max_length=255, blank=True)

View file

@ -315,7 +315,9 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils):
self.assertEqual(len(response.context['data_rows']), 2)
def test_list_submissions_filtering(self):
response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014'})
response = self.client.get(
reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014'}
)
# Check response
self.assertEqual(response.status_code, 200)
@ -337,7 +339,9 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils):
def test_list_submissions_pagination_invalid(self):
self.make_list_submissions()
response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'p': 'Hello World!'})
response = self.client.get(
reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'p': 'Hello World!'}
)
# Check response
self.assertEqual(response.status_code, 200)
@ -359,7 +363,10 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils):
self.assertEqual(response.context['submissions'].number, response.context['submissions'].paginator.num_pages)
def test_list_submissions_csv_export(self):
response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014', 'action': 'CSV'})
response = self.client.get(
reverse('wagtailforms:list_submissions', args=(self.form_page.id, )),
{'date_from': '01/01/2014', 'action': 'CSV'}
)
# Check response
self.assertEqual(response.status_code, 200)
@ -377,7 +384,10 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils):
unicode_form_submission.submit_time = '2014-01-02T12:00:00.000Z'
unicode_form_submission.save()
response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/02/2014', 'action': 'CSV'})
response = self.client.get(
reverse('wagtailforms:list_submissions', args=(self.form_page.id, )),
{'date_from': '01/02/2014', 'action': 'CSV'}
)
# Check response
self.assertEqual(response.status_code, 200)

View file

@ -24,4 +24,7 @@ class FormsMenuItem(MenuItem):
@hooks.register('register_admin_menu_item')
def register_forms_menu_item():
return FormsMenuItem(_('Forms'), urlresolvers.reverse('wagtailforms:index'), name='forms', classnames='icon icon-form', order=700)
return FormsMenuItem(
_('Forms'), urlresolvers.reverse('wagtailforms:index'),
name='forms', classnames='icon icon-form', order=700
)

View file

@ -31,7 +31,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')),
('title', models.CharField(verbose_name='Title', max_length=255)),
('file', models.ImageField(width_field='width', upload_to=wagtail.wagtailimages.models.get_upload_to, verbose_name='File', height_field='height')),
('file', models.ImageField(
width_field='width', upload_to=wagtail.wagtailimages.models.get_upload_to,
verbose_name='File', height_field='height'
)),
('width', models.IntegerField(editable=False)),
('height', models.IntegerField(editable=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
@ -39,8 +42,12 @@ class Migration(migrations.Migration):
('focal_point_y', models.PositiveIntegerField(editable=False, null=True)),
('focal_point_width', models.PositiveIntegerField(editable=False, null=True)),
('focal_point_height', models.PositiveIntegerField(editable=False, null=True)),
('tags', taggit.managers.TaggableManager(verbose_name='Tags', blank=True, help_text=None, to='taggit.Tag', through='taggit.TaggedItem')),
('uploaded_by_user', models.ForeignKey(editable=False, blank=True, null=True, to=settings.AUTH_USER_MODEL)),
('tags', taggit.managers.TaggableManager(
verbose_name='Tags', blank=True, help_text=None, to='taggit.Tag', through='taggit.TaggedItem'
)),
('uploaded_by_user', models.ForeignKey(
editable=False, blank=True, null=True, to=settings.AUTH_USER_MODEL
)),
],
options={
'abstract': False,

View file

@ -8,26 +8,36 @@ def remove_duplicate_renditions(apps, schema_editor):
if schema_editor.connection.vendor == 'mysql':
schema_editor.execute("""
DELETE FROM `wagtailimages_rendition` WHERE CONCAT(image_id, '-', filter_id) IN (
SELECT CONCAT(image_id, '-', filter_id) FROM (SELECT * FROM `wagtailimages_rendition`) as x WHERE `focal_point_key` IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1
SELECT CONCAT(image_id, '-', filter_id)
FROM (SELECT * FROM `wagtailimages_rendition`) AS x
WHERE `focal_point_key` IS NULL
GROUP BY image_id, filter_id
HAVING COUNT(*) > 1
) AND `focal_point_key` IS NULL
""")
elif schema_editor.connection.vendor == 'microsoft':
schema_editor.execute("""
DELETE FROM [wagtailimages_rendition] WHERE CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX)) IN (
SELECT CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX)) FROM [wagtailimages_rendition] WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1
DELETE FROM [wagtailimages_rendition] WHERE CAST(image_id AS VARCHAR(MAX)) + '-' +
CAST(filter_id AS VARCHAR(MAX)) IN (
SELECT CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX))
FROM [wagtailimages_rendition] WHERE focal_point_key IS NULL GROUP BY image_id,
filter_id HAVING COUNT(*) > 1
) AND focal_point_key IS NULL
""")
schema_editor.execute("""
DECLARE @constraint_name VARCHAR(MAX)
SELECT @constraint_name = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME='wagtailimages_rendition' AND CONSTRAINT_TYPE='UNIQUE'
SELECT @constraint_name = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_NAME='wagtailimages_rendition' AND CONSTRAINT_TYPE='UNIQUE'
EXEC('ALTER TABLE [wagtailimages_rendition] DROP CONSTRAINT ' + @constraint_name)
ALTER TABLE [wagtailimages_rendition] ALTER COLUMN [focal_point_key] NVARCHAR(255) NOT NULL
EXEC('ALTER TABLE [wagtailimages_rendition] ADD CONSTRAINT ' + @constraint_name + ' UNIQUE NONCLUSTERED (image_id, filter_id, focal_point_key)')
EXEC('ALTER TABLE [wagtailimages_rendition] ADD CONSTRAINT ' + @constraint_name +
' UNIQUE NONCLUSTERED (image_id, filter_id, focal_point_key)')
""")
else:
schema_editor.execute("""
DELETE FROM wagtailimages_rendition WHERE image_id || '-' || filter_id IN (
SELECT image_id || '-' || filter_id FROM wagtailimages_rendition WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1
SELECT image_id || '-' || filter_id FROM wagtailimages_rendition
WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1
) AND focal_point_key IS NULL
""")

View file

@ -25,7 +25,10 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='image',
name='uploaded_by_user',
field=models.ForeignKey(blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Uploaded by user'),
field=models.ForeignKey(
blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True,
verbose_name='Uploaded by user'
),
),
migrations.AlterField(
model_name='image',

View file

@ -52,15 +52,18 @@ def get_upload_to(instance, filename):
return instance.get_upload_to(filename)
@python_2_unicode_compatible
class AbstractImage(models.Model, TagSearchable):
title = models.CharField(max_length=255, verbose_name=_('title'))
file = models.ImageField(verbose_name=_('file'), upload_to=get_upload_to, width_field='width', height_field='height')
file = models.ImageField(
verbose_name=_('file'), upload_to=get_upload_to, width_field='width', height_field='height'
)
width = models.IntegerField(verbose_name=_('width'), editable=False)
height = models.IntegerField(verbose_name=_('height'), editable=False)
created_at = models.DateTimeField(verbose_name=_('created at'), auto_now_add=True, db_index=True)
uploaded_by_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('uploaded by user'), null=True, blank=True, editable=False)
uploaded_by_user = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=_('uploaded by user'), null=True, blank=True, editable=False
)
tags = TaggableManager(help_text=None, blank=True, verbose_name=_('tags'))
@ -262,7 +265,8 @@ class AbstractImage(models.Model, TagSearchable):
if cache_key:
output_extension = cache_key + '.' + output_extension
output_filename_without_extension = input_filename_without_extension[:(59 - len(output_extension))] # Truncate filename to prevent it going over 60 chars
# Truncate filename to prevent it going over 60 chars
output_filename_without_extension = input_filename_without_extension[:(59 - len(output_extension))]
output_filename = output_filename_without_extension + '.' + output_extension
rendition, created = self.renditions.get_or_create(
@ -346,7 +350,10 @@ def get_image_model():
image_model = apps.get_model(app_label, model_name)
if image_model is None:
raise ImproperlyConfigured("WAGTAILIMAGES_IMAGE_MODEL refers to model '%s' that has not been installed" % settings.WAGTAILIMAGES_IMAGE_MODEL)
raise ImproperlyConfigured(
"WAGTAILIMAGES_IMAGE_MODEL refers to model '%s' that has not been installed" %
settings.WAGTAILIMAGES_IMAGE_MODEL
)
return image_model

View file

@ -24,7 +24,10 @@ def image(parser, token):
try:
name, value = bit.split('=')
except ValueError:
raise template.TemplateSyntaxError("'image' tag should be of the form {% image self.photo max-320x200 [ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}")
raise template.TemplateSyntaxError(
"""'image' tag should be of the form {% image self.photo max-320x200
[ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}"""
)
attrs[name] = parser.compile_filter(value) # setup to resolve context variables as value
return ImageNode(image_expr, filter_spec, attrs=attrs)

View file

@ -130,10 +130,13 @@ class TestImageAddView(TestCase, WagtailTestUtils):
self.assertTemplateUsed(response, 'wagtailimages/images/add.html')
# The form should have an error
self.assertFormError(response, 'form', 'file', "This file is too big ({file_size}). Maximum filesize {max_file_size}.".format(
file_size=filesizeformat(len(file_content)),
max_file_size=filesizeformat(1),
))
self.assertFormError(
response, 'form', 'file',
"This file is too big ({file_size}). Maximum filesize {max_file_size}.".format(
file_size=filesizeformat(len(file_content)),
max_file_size=filesizeformat(1),
)
)
class TestImageEditView(TestCase, WagtailTestUtils):
@ -404,7 +407,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils):
response = self.client.get(reverse('wagtailimages:add_multiple'))
self.assertEqual(response.context['max_filesize'], 1000)
self.assertEqual(response.context['error_max_file_size'], "This file is too big. Maximum filesize 1000\xa0bytes.")
self.assertEqual(
response.context['error_max_file_size'], "This file is too big. Maximum filesize 1000\xa0bytes."
)
def test_add_post(self):
"""
@ -473,7 +478,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils):
self.assertIn('success', response_json)
self.assertIn('error_message', response_json)
self.assertFalse(response_json['success'])
self.assertEqual(response_json['error_message'], "Not a supported image format. Supported formats: GIF, JPEG, PNG.")
self.assertEqual(
response_json['error_message'], "Not a supported image format. Supported formats: GIF, JPEG, PNG."
)
def test_edit_get(self):
"""
@ -562,7 +569,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils):
This tests that a POST request to the delete view deletes the image
"""
# Send request
response = self.client.post(reverse('wagtailimages:delete_multiple', args=(self.image.id, )), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
response = self.client.post(reverse(
'wagtailimages:delete_multiple', args=(self.image.id, )
), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
# Check response
self.assertEqual(response.status_code, 200)
@ -768,7 +777,9 @@ class TestEditOnlyPermissions(TestCase, WagtailTestUtils):
)
# Create a user with change_image permission but not add_image
user = get_user_model().objects.create_user(username='changeonly', email='changeonly@example.com', password='password')
user = get_user_model().objects.create_user(
username='changeonly', email='changeonly@example.com', password='password'
)
change_permission = Permission.objects.get(content_type__app_label='wagtailimages', codename='change_image')
admin_permission = Permission.objects.get(content_type__app_label='wagtailadmin', codename='access_admin')
user.user_permissions.add(change_permission, admin_permission)

View file

@ -140,7 +140,9 @@ class TestImagePermissions(TestCase):
self.owner = User.objects.create_user(username='owner', email='owner@email.com', password='password')
self.editor = User.objects.create_user(username='editor', email='editor@email.com', password='password')
self.editor.groups.add(Group.objects.get(name='Editors'))
self.administrator = User.objects.create_superuser(username='administrator', email='administrator@email.com', password='password')
self.administrator = User.objects.create_superuser(
username='administrator', email='administrator@email.com', password='password'
)
# Owner user must have the add_image permission
self.owner.user_permissions.add(Permission.objects.get(codename='add_image'))
@ -328,7 +330,9 @@ class TestIssue573(TestCase):
# Create an image with a big filename and focal point
image = Image.objects.create(
title="Test image",
file=get_test_image_file('thisisaverylongfilename-abcdefghijklmnopqrstuvwxyz-supercalifragilisticexpialidocious.png'),
file=get_test_image_file(
'thisisaverylongfilename-abcdefghijklmnopqrstuvwxyz-supercalifragilisticexpialidocious.png'
),
focal_point_x=1000,
focal_point_y=1000,
focal_point_width=1000,

View file

@ -46,4 +46,7 @@ class TestImageEmbedHandler(TestCase):
'format': 'left'},
True
)
self.assertIn('<img data-embedtype="image" data-id="1" data-format="left" data-alt="test-alt" class="richtext-image left"', result)
self.assertIn(
'<img data-embedtype="image" data-id="1" data-format="left" '
'data-alt="test-alt" class="richtext-image left"', result
)

View file

@ -45,7 +45,10 @@ class TestImageTag(TestCase):
self.assertEqual(result, '')
def render_image_tag_as(self, image, filter_spec):
temp = template.Template('{% load wagtailimages_tags %}{% image image_obj ' + filter_spec + ' as test_img %}<img {{ test_img.attrs }} />')
temp = template.Template(
'{% load wagtailimages_tags %}{% image image_obj ' + filter_spec +
' as test_img %}<img {{ test_img.attrs }} />'
)
context = template.Context({'image_obj': image})
return temp.render(context)
@ -58,7 +61,10 @@ class TestImageTag(TestCase):
self.assertTrue('alt="Test image"' in result)
def render_image_tag_with_extra_attributes(self, image, title):
temp = template.Template('{% load wagtailimages_tags %}{% image image_obj width-400 class="photo" title=title|lower alt="Alternate" %}')
temp = template.Template(
'{% load wagtailimages_tags %}{% image image_obj width-400 \
class="photo" title=title|lower alt="Alternate" %}'
)
context = template.Context({'image_obj': image, 'title': title})
return temp.render(context)
@ -73,7 +79,9 @@ class TestImageTag(TestCase):
self.assertTrue('title="my wonderful title"' in result)
def render_image_tag_with_filters(self, image):
temp = template.Template('{% load wagtailimages_tags %}{% image image_primary|default:image_alternate width-400 %}')
temp = template.Template(
'{% load wagtailimages_tags %}{% image image_primary|default:image_alternate width-400 %}'
)
context = template.Context({'image_primary': None, 'image_alternate': image})
return temp.render(context)
@ -94,12 +102,21 @@ class TestMissingImage(TestCase):
def test_image_tag_with_missing_image(self):
# the page /events/christmas/ has a missing image as the feed image
response = self.client.get('/events/christmas/')
self.assertContains(response, '<img src="/media/not-found" width="0" height="0" alt="A missing image" class="feed-image">', html=True)
self.assertContains(
response,
'<img src="/media/not-found" width="0" height="0" alt="A missing image" class="feed-image">',
html=True
)
def test_rich_text_with_missing_image(self):
# the page /events/final-event/ has a missing image in the rich text body
response = self.client.get('/events/final-event/')
self.assertContains(response, '<img class="richtext-image full-width" src="/media/not-found" width="0" height="0" alt="where did my image go?">', html=True)
self.assertContains(
response,
'<img class="richtext-image full-width" src="/media/not-found" \
width="0" height="0" alt="where did my image go?">',
html=True
)
class TestFormat(TestCase):
@ -130,7 +147,8 @@ class TestFormat(TestCase):
)
six.assertRegex(
self, result,
'<img data-embedtype="image" data-id="0" data-format="test name" data-alt="test alt text" class="test classnames" src="[^"]+" width="1" height="1" alt="test alt text">',
'<img data-embedtype="image" data-id="0" data-format="test name" '
'data-alt="test alt text" class="test classnames" src="[^"]+" width="1" height="1" alt="test alt text">',
)
def test_image_to_html_no_classnames(self):

View file

@ -112,7 +112,9 @@ def edit(request, image_id):
if image.is_stored_locally():
# Give error if image file doesn't exist
if not os.path.isfile(image.file.path):
messages.error(request, _("The source image file could not be found. Please change the source or delete the image.").format(image.title), buttons=[
messages.error(request, _(
"The source image file could not be found. Please change the source or delete the image."
).format(image.title), buttons=[
messages.button(reverse('wagtailimages:delete', args=(image.id,)), _('Delete'))
])

View file

@ -28,7 +28,10 @@ class ImagesMenuItem(MenuItem):
@hooks.register('register_admin_menu_item')
def register_images_menu_item():
return ImagesMenuItem(_('Images'), urlresolvers.reverse('wagtailimages:index'), name='images', classnames='icon icon-image', order=300)
return ImagesMenuItem(
_('Images'), urlresolvers.reverse('wagtailimages:index'),
name='images', classnames='icon icon-image', order=300
)
@hooks.register('insert_editor_js')

View file

@ -8,7 +8,9 @@ from wagtail.wagtailredirects.models import Redirect
class RedirectForm(forms.ModelForm):
site = forms.ModelChoiceField(label=_("From site"), queryset=Site.objects.all(), required=False, empty_label=_("All sites"))
site = forms.ModelChoiceField(
label=_("From site"), queryset=Site.objects.all(), required=False, empty_label=_("All sites")
)
def __init__(self, *args, **kwargs):
super(RedirectForm, self).__init__(*args, **kwargs)

View file

@ -15,11 +15,20 @@ class Migration(migrations.Migration):
name='Redirect',
fields=[
('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)),
('old_path', models.CharField(verbose_name='Redirect from', max_length=255, unique=True, db_index=True)),
('is_permanent', models.BooleanField(verbose_name='Permanent', default=True, help_text="Recommended. Permanent redirects ensure search engines forget the old page (the 'Redirect from') and index the new page instead.")),
('old_path', models.CharField(
verbose_name='Redirect from', max_length=255, unique=True, db_index=True
)),
('is_permanent', models.BooleanField(
verbose_name='Permanent', default=True, help_text="""Recommended. Permanent redirects \
ensure search engines forget the old page (the 'Redirect from') and index the new page instead."""
)),
('redirect_link', models.URLField(blank=True, verbose_name='Redirect to any URL')),
('redirect_page', models.ForeignKey(blank=True, null=True, verbose_name='Redirect to a page', to='wagtailcore.Page')),
('site', models.ForeignKey(blank=True, to='wagtailcore.Site', editable=False, null=True, related_name='redirects')),
('redirect_page', models.ForeignKey(
blank=True, null=True, verbose_name='Redirect to a page', to='wagtailcore.Page'
)),
('site', models.ForeignKey(
blank=True, to='wagtailcore.Site', editable=False, null=True, related_name='redirects'
)),
],
options={
},

View file

@ -18,6 +18,9 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='redirect',
name='site',
field=models.ForeignKey(related_name='redirects', blank=True, editable=False, to='wagtailcore.Site', null=True, verbose_name='Site'),
field=models.ForeignKey(
related_name='redirects', blank=True, editable=False,
to='wagtailcore.Site', null=True, verbose_name='Site'
),
),
]

View file

@ -14,6 +14,8 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='redirect',
name='site',
field=models.ForeignKey(null=True, to='wagtailcore.Site', verbose_name='Site', blank=True, related_name='redirects'),
field=models.ForeignKey(
null=True, to='wagtailcore.Site', verbose_name='Site', blank=True, related_name='redirects'
),
),
]

View file

@ -7,8 +7,13 @@ from django.utils.translation import ugettext_lazy as _
class Redirect(models.Model):
old_path = models.CharField(verbose_name=_("redirect from"), max_length=255, db_index=True)
site = models.ForeignKey('wagtailcore.Site', verbose_name=_('site'), null=True, blank=True, related_name='redirects', db_index=True)
is_permanent = models.BooleanField(verbose_name=_("permanent"), default=True, help_text=_("Recommended. Permanent redirects ensure search engines forget the old page (the 'Redirect from') and index the new page instead."))
site = models.ForeignKey(
'wagtailcore.Site', verbose_name=_('site'), null=True, blank=True, related_name='redirects', db_index=True
)
is_permanent = models.BooleanField(verbose_name=_("permanent"), default=True, help_text=_(
"Recommended. Permanent redirects ensure search engines "
"forget the old page (the 'Redirect from') and index the new page instead."
))
redirect_page = models.ForeignKey('wagtailcore.Page', verbose_name=_("redirect to a page"), null=True, blank=True)
redirect_link = models.URLField(verbose_name=_("redirect to any URL"), blank=True)

View file

@ -16,26 +16,62 @@ class TestRedirects(TestCase):
path = normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')
# Test against equivalant paths
self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # The exact same URL
self.assertEqual(path, normalise_path('http://mywebsite.com:8000/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Scheme, hostname and port ignored
self.assertEqual(path, normalise_path('Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Leading slash can be omitted
self.assertEqual(path, normalise_path('Hello/world.html/;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Trailing slashes are ignored
self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2#cool')) # Fragments are ignored
self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?Baz=quux2&foo=Bar')) # Order of query string parameters is ignored
self.assertEqual(path, normalise_path('/Hello/world.html;buzz=five;fizz=three?foo=Bar&Baz=quux2')) # Order of parameters is ignored
self.assertEqual(path, normalise_path(' /Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Leading whitespace
self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2 ')) # Trailing whitespace
self.assertEqual(path, normalise_path( # The exact same URL
'/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Scheme, hostname and port ignored
'http://mywebsite.com:8000/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Leading slash can be omitted
'Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Trailing slashes are ignored
'Hello/world.html/;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Fragments are ignored
'/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2#cool'
))
self.assertEqual(path, normalise_path( # Order of query string parameters is ignored
'/Hello/world.html;fizz=three;buzz=five?Baz=quux2&foo=Bar'
))
self.assertEqual(path, normalise_path( # Order of parameters is ignored
'/Hello/world.html;buzz=five;fizz=three?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Leading whitespace
' /Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertEqual(path, normalise_path( # Trailing whitespace
'/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2 '
))
# Test against different paths
self.assertNotEqual(path, normalise_path('/hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # 'hello' is lowercase
self.assertNotEqual(path, normalise_path('/Hello/world;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # No '.html'
self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=bar&Baz=Quux2')) # Query string parameter value has wrong case
self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&baz=quux2')) # Query string parameter name has wrong case
self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=Five?foo=Bar&Baz=quux2')) # Parameter value has wrong case
self.assertNotEqual(path, normalise_path('/Hello/world.html;Fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Parameter name has wrong case
self.assertNotEqual(path, normalise_path('/Hello/world.html?foo=Bar&Baz=quux2')) # Missing params
self.assertNotEqual(path, normalise_path('/Hello/WORLD.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # 'WORLD' is uppercase
self.assertNotEqual(path, normalise_path('/Hello/world.htm;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # '.htm' is not the same as '.html'
self.assertNotEqual(path, normalise_path( # 'hello' is lowercase
'/hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # No '.html'
'/Hello/world;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # Query string parameter value has wrong case
'/Hello/world.html;fizz=three;buzz=five?foo=bar&Baz=Quux2'
))
self.assertNotEqual(path, normalise_path( # Query string parameter name has wrong case
'/Hello/world.html;fizz=three;buzz=five?foo=Bar&baz=quux2'
))
self.assertNotEqual(path, normalise_path( # Parameter value has wrong case
'/Hello/world.html;fizz=three;buzz=Five?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # Parameter name has wrong case
'/Hello/world.html;Fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # Missing params
'/Hello/world.html?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # 'WORLD' is uppercase
'/Hello/WORLD.html;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
self.assertNotEqual(path, normalise_path( # '.htm' is not the same as '.html'
'/Hello/world.htm;fizz=three;buzz=five?foo=Bar&Baz=quux2'
))
# Normalise some rubbish to make sure it doesn't crash
normalise_path('This is not a URL')
@ -67,7 +103,9 @@ class TestRedirects(TestCase):
def test_redirect_stripping_query_string(self):
# Create a redirect which includes a query string
redirect_with_query_string = models.Redirect(old_path='/redirectme?foo=Bar', redirect_link='/with-query-string-only')
redirect_with_query_string = models.Redirect(
old_path='/redirectme?foo=Bar', redirect_link='/with-query-string-only'
)
redirect_with_query_string.save()
# ... and another redirect without the query string
@ -348,7 +386,9 @@ class TestRedirectsDeleteView(TestCase, WagtailTestUtils):
return self.client.get(reverse('wagtailredirects:delete', args=(redirect_id or self.redirect.id, )), params)
def post(self, post_data={}, redirect_id=None):
return self.client.post(reverse('wagtailredirects:delete', args=(redirect_id or self.redirect.id, )), post_data)
return self.client.post(reverse(
'wagtailredirects:delete', args=(redirect_id or self.redirect.id, )
), post_data)
def test_simple(self):
response = self.get()

View file

@ -12,7 +12,11 @@ from wagtail.wagtailredirects import models
from wagtail.wagtailredirects.forms import RedirectForm
@any_permission_required('wagtailredirects.add_redirect', 'wagtailredirects.change_redirect', 'wagtailredirects.delete_redirect')
@any_permission_required(
'wagtailredirects.add_redirect',
'wagtailredirects.change_redirect',
'wagtailredirects.delete_redirect'
)
@vary_on_headers('X-Requested-With')
def index(request):
query_string = request.GET.get('q', "")
@ -46,7 +50,9 @@ def index(request):
'ordering': ordering,
'redirects': redirects,
'query_string': query_string,
'search_form': SearchForm(data=dict(q=query_string) if query_string else None, placeholder=_("Search redirects")),
'search_form': SearchForm(
data=dict(q=query_string) if query_string else None, placeholder=_("Search redirects")
),
})

View file

@ -27,7 +27,9 @@ class RedirectsMenuItem(MenuItem):
@hooks.register('register_settings_menu_item')
def register_redirects_menu_item():
return RedirectsMenuItem(_('Redirects'), urlresolvers.reverse('wagtailredirects:index'), classnames='icon icon-redirect', order=800)
return RedirectsMenuItem(
_('Redirects'), urlresolvers.reverse('wagtailredirects:index'), classnames='icon icon-redirect', order=800
)
@hooks.register('register_permissions')

View file

@ -54,13 +54,19 @@ class BaseSearchQuery(object):
field = self._get_filterable_field(field_attname)
if field is None:
raise FieldError('Cannot filter search results with field "' + field_attname + '". Please add index.FilterField(\'' + field_attname + '\') to ' + self.queryset.model.__name__ + '.search_fields.')
raise FieldError(
'Cannot filter search results with field "' + field_attname + '". Please add index.FilterField(\''
+ field_attname + '\') to ' + self.queryset.model.__name__ + '.search_fields.'
)
# Process the lookup
result = self._process_lookup(field, lookup, value)
if result is None:
raise FilterError('Could not apply filter on search results: "' + field_attname + '__' + lookup + ' = ' + text_type(value) + '". Lookup "' + lookup + '"" not recognosed.')
raise FilterError(
'Could not apply filter on search results: "' + field_attname + '__'
+ lookup + ' = ' + text_type(value) + '". Lookup "' + lookup + '"" not recognosed.'
)
return result
@ -208,7 +214,8 @@ class BaseSearch(object):
def delete(self, obj):
raise NotImplementedError
def search(self, query_string, model_or_queryset, fields=None, filters=None, prefetch_related=None, operator=None, order_by_relevance=True):
def search(self, query_string, model_or_queryset, fields=None, filters=None,
prefetch_related=None, operator=None, order_by_relevance=True):
# Find model/queryset
if isinstance(model_or_queryset, QuerySet):
model = model_or_queryset.model
@ -241,5 +248,7 @@ class BaseSearch(object):
raise ValueError("operator must be either 'or' or 'and'")
# Search
search_query = self.search_query_class(queryset, query_string, fields=fields, operator=operator, order_by_relevance=order_by_relevance)
search_query = self.search_query_class(
queryset, query_string, fields=fields, operator=operator, order_by_relevance=order_by_relevance
)
return self.search_results_class(self, search_query)

View file

@ -371,7 +371,11 @@ class ElasticSearchQuery(BaseSearchQuery):
class ElasticSearchResults(BaseSearchResults):
def _get_es_body(self, for_count=False):
# If to_es has been overridden, call it and raise a deprecation warning
if isinstance(self.query, ElasticSearchQuery) and six.get_method_function(self.query.to_es) != ElasticSearchQuery.to_es:
if (
isinstance(self.query, ElasticSearchQuery)
and six.get_method_function(self.query.to_es)
!= ElasticSearchQuery.to_es
):
warnings.warn(
"The .to_es() method on Elasticsearch query classes is deprecated. "
"Please rename {class_name}.to_es() to {class_name}.get_query()".format(
@ -465,7 +469,9 @@ class ElasticSearchIndexRebuilder(object):
mapping = ElasticSearchMapping(model)
# Put mapping
self.es.indices.put_mapping(index=self.index_name, doc_type=mapping.get_document_type(), body=mapping.get_mapping())
self.es.indices.put_mapping(
index=self.index_name, doc_type=mapping.get_document_type(), body=mapping.get_mapping()
)
def add_items(self, model, obj_list):
if not class_is_indexed(model):
@ -612,7 +618,9 @@ class ElasticSearch(BaseSearch):
mapping = ElasticSearchMapping(model)
# Put mapping
self.es.indices.put_mapping(index=self.es_index, doc_type=mapping.get_document_type(), body=mapping.get_mapping())
self.es.indices.put_mapping(
index=self.es_index, doc_type=mapping.get_document_type(), body=mapping.get_mapping()
)
def refresh_index(self):
self.es.indices.refresh(self.es_index)
@ -626,7 +634,9 @@ class ElasticSearch(BaseSearch):
mapping = ElasticSearchMapping(obj.__class__)
# Add document to index
self.es.index(self.es_index, mapping.get_document_type(), mapping.get_document(obj), id=mapping.get_document_id(obj))
self.es.index(
self.es_index, mapping.get_document_type(), mapping.get_document(obj), id=mapping.get_document_id(obj)
)
def add_bulk(self, model, obj_list):
if not class_is_indexed(model):

View file

@ -49,7 +49,9 @@ class Query(models.Model):
@classmethod
def get_most_popular(cls, date_since=None):
# TODO: Implement date_since
return cls.objects.filter(daily_hits__isnull=False).annotate(_hits=models.Sum('daily_hits__hits')).distinct().order_by('-_hits')
return (cls.objects.filter(daily_hits__isnull=False)
.annotate(_hits=models.Sum('daily_hits__hits'))
.distinct().order_by('-_hits'))
class QueryDailyHits(models.Model):

View file

@ -141,8 +141,11 @@ class BackendTests(WagtailTestUtils):
self.assertEqual(set(results), set())
# Run update_index command
with self.ignore_deprecation_warnings(): # ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions
management.call_command('update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO())
with self.ignore_deprecation_warnings():
# ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions
management.call_command(
'update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO()
)
results = self.backend.search(None, models.SearchTest)
self.assertEqual(set(results), {self.testa, self.testb, self.testc.searchtest_ptr, self.testd.searchtest_ptr})
@ -167,7 +170,9 @@ class TestBackendLoader(TestCase):
self.assertIsInstance(db, DBSearch)
def test_nonexistent_backend_import(self):
self.assertRaises(InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist')
self.assertRaises(
InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist'
)
def test_invalid_backend_import(self):
self.assertRaises(InvalidSearchBackendError, get_search_backend, backend="I'm not a backend!")

View file

@ -205,7 +205,9 @@ class TestElasticSearchBackend(BackendTests, TestCase):
self.assertEqual(list(results), [a, b])
# Do a search ordered by published date
results = self.backend.search("Hello", models.SearchTest.objects.order_by('-published_date'), order_by_relevance=False)
results = self.backend.search(
"Hello", models.SearchTest.objects.order_by('-published_date'), order_by_relevance=False
)
self.assertEqual(list(results), [b, a])
def test_and_operator_with_single_field(self):
@ -233,14 +235,19 @@ class TestElasticSearchBackend(BackendTests, TestCase):
class TestElasticSearchQuery(TestCase):
def assertDictEqual(self, a, b):
default = JSONSerializer().default
self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default))
self.assertEqual(
json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)
)
def test_simple(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_none_query_string(self):
@ -248,7 +255,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.all(), None)
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match_all': {}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'match_all': {}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_and_operator(self):
@ -256,7 +266,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", operator='and')
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials'], 'operator': 'and'}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials'], 'operator': 'and'}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_filter(self):
@ -264,7 +277,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'term': {'title_filter': 'Test'}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_and_filter(self):
@ -272,7 +288,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title="Test", live=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
# Make sure field filters are sorted (as they can be in any order which may cause false positives)
query = query.get_query()
@ -291,7 +310,10 @@ class TestElasticSearchQuery(TestCase):
field_filters[:] = sorted(field_filters, key=lambda f: list(f['term'].keys())[0])
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query, expected_result)
def test_negated_filter(self):
@ -299,7 +321,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.exclude(live=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'not': {'term': {'live_filter': True}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_fields(self):
@ -307,7 +332,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title'])
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'match': {'title': 'Hello'}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_fields_with_and_operator(self):
@ -315,7 +343,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title'], operator='and')
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': {'query': 'Hello', 'operator': 'and'}}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'match': {'title': {'query': 'Hello', 'operator': 'and'}}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_multiple_fields(self):
@ -323,15 +354,23 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title', 'content'])
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello'}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello'}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_multiple_fields_with_and_operator(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title', 'content'], operator='and')
query = ElasticSearchQuery(
models.SearchTest.objects.all(), "Hello", fields=['title', 'content'], operator='and'
)
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello', 'operator': 'and'}}}}
expected_result = {'filtered': {
'filter': {'prefix': {'content_type': 'searchtests_searchtest'}},
'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello', 'operator': 'and'}}
}}
self.assertDictEqual(query.get_query(), expected_result)
def test_exact_lookup(self):
@ -339,7 +378,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title__exact="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'term': {'title_filter': 'Test'}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_none_lookup(self):
@ -347,7 +389,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title=None), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'missing': {'field': 'title_filter'}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_isnull_true_lookup(self):
@ -355,7 +400,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'missing': {'field': 'title_filter'}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_isnull_false_lookup(self):
@ -363,7 +411,10 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=False), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'not': {'missing': {'field': 'title_filter'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_startswith_lookup(self):
@ -371,41 +422,64 @@ class TestElasticSearchQuery(TestCase):
query = ElasticSearchQuery(models.SearchTest.objects.filter(title__startswith="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'prefix': {'title_filter': 'Test'}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_gt_lookup(self):
# This also tests conversion of python dates to strings
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello")
query = ElasticSearchQuery(
models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello"
)
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'range': {'published_date_filter': {'gt': '2014-04-29'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_lt_lookup(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello")
query = ElasticSearchQuery(
models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello"
)
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'range': {'published_date_filter': {'lt': '2014-04-29'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_gte_lookup(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello")
query = ElasticSearchQuery(
models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello"
)
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'range': {'published_date_filter': {'gte': '2014-04-29'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_lte_lookup(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello")
query = ElasticSearchQuery(
models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello"
)
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'range': {'published_date_filter': {'lte': '2014-04-29'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_range_lookup(self):
@ -413,15 +487,22 @@ class TestElasticSearchQuery(TestCase):
end_date = datetime.datetime(2014, 8, 19)
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello")
query = ElasticSearchQuery(
models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello"
)
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [
{'prefix': {'content_type': 'searchtests_searchtest'}},
{'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}
]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.get_query(), expected_result)
def test_custom_ordering(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.order_by('published_date'), "Hello", order_by_relevance=False)
query = ElasticSearchQuery(
models.SearchTest.objects.order_by('published_date'), "Hello", order_by_relevance=False
)
# Check it
expected_result = [{'published_date_filter': 'asc'}]
@ -429,7 +510,9 @@ class TestElasticSearchQuery(TestCase):
def test_custom_ordering_reversed(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.order_by('-published_date'), "Hello", order_by_relevance=False)
query = ElasticSearchQuery(
models.SearchTest.objects.order_by('-published_date'), "Hello", order_by_relevance=False
)
# Check it
expected_result = [{'published_date_filter': 'desc'}]
@ -437,7 +520,9 @@ class TestElasticSearchQuery(TestCase):
def test_custom_ordering_multiple(self):
# Create a query
query = ElasticSearchQuery(models.SearchTest.objects.order_by('published_date', 'live'), "Hello", order_by_relevance=False)
query = ElasticSearchQuery(
models.SearchTest.objects.order_by('published_date', 'live'), "Hello", order_by_relevance=False
)
# Check it
expected_result = [{'published_date_filter': 'asc'}, {'live_filter': 'asc'}]
@ -447,7 +532,9 @@ class TestElasticSearchQuery(TestCase):
class TestElasticSearchResults(TestCase):
def assertDictEqual(self, a, b):
default = JSONSerializer().default
self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default))
self.assertEqual(
json.dumps(a, sort_keys=True, default=default), json.dumps
)
def setUp(self):
self.objects = []
@ -599,7 +686,9 @@ class TestElasticSearchResults(TestCase):
@mock.patch('elasticsearch.Elasticsearch.search')
def test_result_order(self, search):
search.return_value = self.construct_search_response([self.objects[0].id, self.objects[1].id, self.objects[2].id])
search.return_value = self.construct_search_response(
[self.objects[0].id, self.objects[1].id, self.objects[2].id]
)
results = list(self.get_results()) # Must cast to list so we only create one query
self.assertEqual(results[0], self.objects[0])
@ -608,7 +697,9 @@ class TestElasticSearchResults(TestCase):
@mock.patch('elasticsearch.Elasticsearch.search')
def test_result_order_2(self, search):
search.return_value = self.construct_search_response([self.objects[2].id, self.objects[1].id, self.objects[0].id])
search.return_value = self.construct_search_response(
[self.objects[2].id, self.objects[1].id, self.objects[0].id]
)
results = list(self.get_results()) # Must cast to list so we only create one query
self.assertEqual(results[0], self.objects[2])
@ -619,7 +710,9 @@ class TestElasticSearchResults(TestCase):
class TestElasticSearchMapping(TestCase):
def assertDictEqual(self, a, b):
default = JSONSerializer().default
self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default))
self.assertEqual(
json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)
)
def setUp(self):
# Create ES mapping
@ -681,7 +774,9 @@ class TestElasticSearchMapping(TestCase):
class TestElasticSearchMappingInheritance(TestCase):
def assertDictEqual(self, a, b):
default = JSONSerializer().default
self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default))
self.assertEqual(
json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)
)
def setUp(self):
# Create ES mapping
@ -820,7 +915,9 @@ class TestBackendConfiguration(TestCase):
class TestRebuilder(TestCase):
def assertDictEqual(self, a, b):
default = JSONSerializer().default
self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default))
self.assertEqual(
json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)
)
def setUp(self):
self.backend = get_search_backend('elasticsearch')
@ -847,13 +944,17 @@ class TestRebuilder(TestCase):
def test_start_deletes_existing_index(self):
# Put an alias into the index so we can check it was deleted
self.es.indices.put_alias(name='this_index_should_be_deleted', index=self.backend.es_index)
self.assertTrue(self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index))
self.assertTrue(
self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index)
)
# Run start
self.rebuilder.start()
# The alias should be gone (proving the index was deleted and recreated)
self.assertFalse(self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index))
self.assertFalse(
self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index)
)
def test_add_model(self):
self.rebuilder.start()
@ -866,13 +967,15 @@ class TestRebuilder(TestCase):
response = self.es.indices.get_mapping(self.backend.es_index, mapping.get_document_type())
# Make some minor tweaks to the mapping so it matches what is in ES
# These are generally minor issues with the way Wagtail is generating the mapping that are being cleaned up by Elasticsearch
# These are generally minor issues with the way Wagtail is
# generating the mapping that are being cleaned up by Elasticsearch
# TODO: Would be nice to fix these
expected_mapping = mapping.get_mapping()
expected_mapping['searchtests_searchtest']['properties']['pk']['store'] = True
expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('index')
expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('include_in_all')
expected_mapping['searchtests_searchtest']['properties']['published_date_filter']['format'] = 'dateOptionalTime'
expected_mapping['searchtests_searchtest']['properties']['published_date_filter']['format'] = \
'dateOptionalTime'
expected_mapping['searchtests_searchtest']['properties']['published_date_filter'].pop('index')
self.assertDictEqual(expected_mapping, response[self.backend.es_index]['mappings'])
@ -916,7 +1019,9 @@ class TestAtomicRebuilder(TestCase):
self.rebuilder.start()
# Check that the alias doesn't point to new index
self.assertFalse(self.es.indices.exists_alias(name=self.rebuilder.alias_name, index=self.rebuilder.index_name))
self.assertFalse(
self.es.indices.exists_alias(name=self.rebuilder.alias_name, index=self.rebuilder.index_name)
)
# Run finish
self.rebuilder.finish()

View file

@ -30,10 +30,12 @@ def chooser(request, get_results=False):
'queries': queries,
})
else:
return render_modal_workflow(request, 'wagtailsearch/queries/chooser/chooser.html', 'wagtailsearch/queries/chooser/chooser.js', {
'queries': queries,
'searchform': searchform,
})
return render_modal_workflow(
request, 'wagtailsearch/queries/chooser/chooser.html', 'wagtailsearch/queries/chooser/chooser.js', {
'queries': queries,
'searchform': searchform,
}
)
def chooserresults(request):

View file

@ -27,7 +27,8 @@ class SitesMenuItem(MenuItem):
@hooks.register('register_settings_menu_item')
def register_sites_menu_item():
return SitesMenuItem(_('Sites'), urlresolvers.reverse('wagtailsites:index'), classnames='icon icon-site', order=602)
return SitesMenuItem(_('Sites'), urlresolvers.reverse('wagtailsites:index'),
classnames='icon icon-site', order=602)
@hooks.register('register_permissions')

View file

@ -314,7 +314,8 @@ class TestGroupEditView(TestCase, WagtailTestUtils):
}
for k, v in six.iteritems(post_defaults):
post_data[k] = post_data.get(k, v)
return self.client.post(reverse('wagtailusers_groups:edit', args=(group_id or self.test_group.id, )), post_data)
return self.client.post(reverse(
'wagtailusers_groups:edit', args=(group_id or self.test_group.id, )), post_data)
def add_non_registered_perm(self):
# Some groups may have django permissions assigned that are not