Skip to content

Commit 328959d

Browse files
committed
The build_solr_schema command can now write directly to a file. Also includes tests for the new overrides.
1 parent 8cef7e7 commit 328959d

File tree

8 files changed

+124
-15
lines changed

8 files changed

+124
-15
lines changed
Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,55 @@
1+
from optparse import make_option
12
import sys
2-
from django.core.management.base import NoArgsCommand
3+
from django.core.management.base import BaseCommand
34
from django.template import loader, Context
4-
from haystack.constants import DEFAULT_OPERATOR
5+
from haystack.constants import ID, DJANGO_CT, DJANGO_ID, DEFAULT_OPERATOR
56

67

7-
class Command(NoArgsCommand):
8+
class Command(BaseCommand):
89
help = "Generates a Solr schema that reflects the indexes."
10+
base_options = (
11+
make_option("-f", "--filename", action="store", type="string", dest="filename",
12+
help='If provided, directs output to a file instead of stdout.'),
13+
)
14+
option_list = BaseCommand.option_list + base_options
915

10-
def handle_noargs(self, **options):
16+
def handle(self, **options):
1117
"""Generates a Solr schema that reflects the indexes."""
18+
schema_xml = self.build_template()
19+
20+
if options.get('filename'):
21+
self.write_file(options.get('filename'), schema_xml)
22+
else:
23+
self.print_stdout(schema_xml)
24+
25+
def build_context(self):
1226
# Cause the default site to load.
13-
from django.conf import settings
1427
from haystack import backend, site
15-
1628
content_field_name, fields = backend.SearchBackend().build_schema(site.all_searchfields())
17-
18-
t = loader.get_template('search_configuration/solr.xml')
19-
c = Context({
29+
return Context({
2030
'content_field_name': content_field_name,
2131
'fields': fields,
2232
'default_operator': DEFAULT_OPERATOR,
33+
'ID': ID,
34+
'DJANGO_CT': DJANGO_CT,
35+
'DJANGO_ID': DJANGO_ID,
2336
})
24-
schema_xml = t.render(c)
37+
38+
def build_template(self):
39+
t = loader.get_template('search_configuration/solr.xml')
40+
c = self.build_context()
41+
return t.render(c)
42+
43+
def print_stdout(self, schema_xml):
2544
sys.stderr.write("\n")
2645
sys.stderr.write("\n")
2746
sys.stderr.write("\n")
2847
sys.stderr.write("Save the following output to 'schema.xml' and place it in your Solr configuration directory.\n")
2948
sys.stderr.write("--------------------------------------------------------------------------------------------\n")
3049
sys.stderr.write("\n")
3150
print schema_xml
51+
52+
def write_file(self, filename, schema_xml):
53+
schema_file = open(filename, 'w')
54+
schema_file.write(schema_xml)
55+
schema_file.close()

haystack/templates/search_configuration/solr.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@
6464

6565
<fields>
6666
<!-- general -->
67-
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
68-
<field name="django_ct" type="string" indexed="true" stored="true" multiValued="false" />
69-
<field name="django_id" type="string" indexed="true" stored="true" multiValued="false" />
67+
<field name="{{ ID }}" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
68+
<field name="{{ DJANGO_CT }}" type="string" indexed="true" stored="true" multiValued="false" />
69+
<field name="{{ DJANGO_ID }}" type="string" indexed="true" stored="true" multiValued="false" />
7070

7171
<dynamicField name="*_i" type="sint" indexed="true" stored="true"/>
7272
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
@@ -83,7 +83,7 @@
8383
</fields>
8484

8585
<!-- field to use to determine and enforce document uniqueness. -->
86-
<uniqueKey>id</uniqueKey>
86+
<uniqueKey>{{ ID }}</uniqueKey>
8787

8888
<!-- field for the QueryParser to use when an explicit fieldname is absent -->
8989
<defaultSearchField>{{ content_field_name }}</defaultSearchField>

tests/overrides/__init__.py

Whitespace-only changes.

tests/overrides/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Blank so I look like an app.

tests/overrides/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from overrides.tests.altered_internal_names import *
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from django.conf import settings
2+
from django.test import TestCase
3+
from haystack import site, indexes
4+
from haystack.backends.solr_backend import SearchBackend, SearchQuery
5+
from haystack.management.commands.build_solr_schema import Command
6+
from haystack.query import SQ
7+
from core.models import MockModel, AnotherMockModel
8+
9+
10+
class MockModelSearchIndex(indexes.SearchIndex):
11+
text = indexes.CharField(model_attr='foo', document=True)
12+
name = indexes.CharField(model_attr='author')
13+
pub_date = indexes.DateField(model_attr='pub_date')
14+
15+
16+
class AlteredInternalNamesTestCase(TestCase):
17+
def test_altered_names(self):
18+
sq = SearchQuery(backend=SearchBackend())
19+
20+
sq.add_filter(SQ(content='hello'))
21+
sq.add_model(MockModel)
22+
self.assertEqual(sq.build_query(), u'(hello) AND (my_django_ct:core.mockmodel)')
23+
24+
sq.add_model(AnotherMockModel)
25+
self.assertEqual(sq.build_query(), u'(hello) AND (my_django_ct:core.anothermockmodel OR my_django_ct:core.mockmodel)')
26+
27+
def test_solr_schema(self):
28+
site.register(MockModel, MockModelSearchIndex)
29+
30+
command = Command()
31+
self.assertEqual(command.build_context().dicts[0], {
32+
'DJANGO_ID': 'my_django_id',
33+
'content_field_name': 'text',
34+
'fields': [
35+
{
36+
'indexed': 'true',
37+
'type': 'text',
38+
'stored': 'true',
39+
'field_name': 'text',
40+
'multi_valued': 'false'
41+
},
42+
{
43+
'indexed': 'true',
44+
'type': 'date',
45+
'stored': 'true',
46+
'field_name': 'pub_date',
47+
'multi_valued': 'false'
48+
},
49+
{
50+
'indexed': 'true',
51+
'type': 'text',
52+
'stored': 'true',
53+
'field_name': 'name',
54+
'multi_valued': 'false'
55+
}
56+
],
57+
'DJANGO_CT': 'my_django_ct',
58+
'default_operator': 'AND',
59+
'ID': 'my_id'
60+
})
61+
62+
schema_xml = command.build_template()
63+
self.assertTrue('<uniqueKey>my_id</uniqueKey>' in schema_xml)
64+
self.assertTrue('<field name="my_id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>' in schema_xml)
65+
self.assertTrue('<field name="my_django_ct" type="string" indexed="true" stored="true" multiValued="false" />' in schema_xml)
66+
self.assertTrue('<field name="my_django_id" type="string" indexed="true" stored="true" multiValued="false" />' in schema_xml)

tests/overrides_settings.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from settings import *
2+
3+
INSTALLED_APPS += [
4+
'overrides',
5+
]
6+
7+
HAYSTACK_SEARCH_ENGINE = 'solr'
8+
HAYSTACK_SOLR_URL = 'http://localhost:9001/solr/test_default'
9+
HAYSTACK_INCLUDE_SPELLING = True
10+
11+
HAYSTACK_ID_FIELD = 'my_id'
12+
HAYSTACK_DJANGO_CT_FIELD = 'my_django_ct'
13+
HAYSTACK_DJANGO_ID_FIELD = 'my_django_id'

tests/run_all_tests.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ django-admin.py test whoosh_tests --settings=whoosh_settings
1818
echo ""
1919

2020
echo "** SITE REG **"
21-
django-admin.py test site_registration --settings=site_registration_settings
21+
django-admin.py test site_registration --settings=site_registration_settings
22+
23+
echo "** OVERRIDES **"
24+
django-admin.py test overrides --settings=overrides_settings
25+
echo ""

0 commit comments

Comments
 (0)