Add a check that the declared search_fields exist

pull/2426/merge
Josh Schneier 2016-03-31 22:02:46 -04:00 zatwierdzone przez Matt Westcott
rodzic f1913bd748
commit 1dad100695
5 zmienionych plików z 44 dodań i 1 usunięć

Wyświetl plik

@ -17,6 +17,7 @@ Changelog
* Add new EmailBlock and IntegerBlock (Oktay Altay)
* Added a new FloatBlock, DecimalBlock and a RegexBlock (Oktay Altay, Andy Babic)
* Wagtail version number is now shown on the settings menu (Chris Rogers)
* Added a system check to validate that fields listed in `search_fields` are defined on the model (Josh Schneier)
* Fix: Email templates and document uploader now support custom `STATICFILES_STORAGE` (Jonny Scholes)
* Fix: Removed alignment options (deprecated in HTML and not rendered by Wagtail) from `TableBlock` context menu (Moritz Pfeiffer)
* Fix: Fixed incorrect CSS path on ModelAdmin's "choose a parent page" view

Wyświetl plik

@ -32,6 +32,7 @@ Minor features
* Added new EmailBlock and IntegerBlock (Oktay Altay)
* Added a new FloatBlock, DecimalBlock and a RegexBlock (Oktay Altay, Andy Babic)
* Wagtail version number is now shown on the settings menu (Chris Rogers)
* Added a system check to validate that fields listed in ``search_fields`` are defined on the model (Josh Schneier)
Bug fixes

Wyświetl plik

@ -6,7 +6,7 @@ from taggit.managers import TaggableManager
from wagtail.wagtailsearch import index
class SearchTest(models.Model, index.Indexed):
class SearchTest(index.Indexed, models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
live = models.BooleanField(default=False)

Wyświetl plik

@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
import logging
from django.apps import apps
from django.core import checks
from django.db import models
from django.db.models.fields import FieldDoesNotExist
from django.db.models.fields.related import ForeignObjectRel, OneToOneRel, RelatedField
@ -85,6 +86,34 @@ class Indexed(object):
"""
return self
@classmethod
def _has_field(cls, name):
try:
cls._meta.get_field(name)
return True
except models.fields.FieldDoesNotExist:
return hasattr(cls, name)
@classmethod
def check(cls, **kwargs):
errors = super(Indexed, cls).check(**kwargs)
errors.extend(cls._check_search_fields(**kwargs))
return errors
@classmethod
def _check_search_fields(cls, **kwargs):
errors = []
for field in cls.get_search_fields():
message = "{model}.search_fields contains field '{name}' but it doesn't exist"
if not cls._has_field(field.field_name):
errors.append(
checks.Warning(
message.format(model=cls.__name__, name=field.field_name),
obj=cls,
)
)
return errors
search_fields = SearchFieldsShouldBeAList([], name='search_fields on Indexed subclasses')

Wyświetl plik

@ -1,5 +1,6 @@
from __future__ import absolute_import, unicode_literals
from django.core import checks
from django.test import TestCase
from wagtail.tests.search import models
@ -68,3 +69,14 @@ class TestSearchFields(TestCase):
self.assertEqual(len(cls.get_search_fields()), 2)
self.assertEqual(len(cls.get_searchable_search_fields()), 1)
self.assertEqual(len(cls.get_filterable_search_fields()), 1)
def test_checking_search_fields(self):
models.SearchTest.search_fields += [index.SearchField('foo')]
expected_errors = [
checks.Warning(
"SearchTest.search_fields contains field 'foo' but it doesn't exist",
obj=models.SearchTest
)
]
errors = models.SearchTest.check()
self.assertEqual(errors, expected_errors)