Skip to content

Commit 1ee1037

Browse files
committed
✨ Let's start!
0 parents  commit 1ee1037

28 files changed

+908
-0
lines changed

.gitignore

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Python template
3+
# Byte-compiled / optimized / DLL files
4+
__pycache__/
5+
*.py[cod]
6+
*$py.class
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
build/
14+
develop-eggs/
15+
dist/
16+
downloads/
17+
eggs/
18+
.eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
.hypothesis/
50+
51+
# Translations
52+
*.mo
53+
*.pot
54+
55+
# Django stuff:
56+
*.log
57+
.static_storage/
58+
.media/
59+
local_settings.py
60+
61+
# Flask stuff:
62+
instance/
63+
.webassets-cache
64+
65+
# Scrapy stuff:
66+
.scrapy
67+
68+
# Sphinx documentation
69+
docs/_build/
70+
71+
# PyBuilder
72+
target/
73+
74+
# Jupyter Notebook
75+
.ipynb_checkpoints
76+
77+
# pyenv
78+
.python-version
79+
80+
# celery beat schedule file
81+
celerybeat-schedule
82+
83+
# SageMath parsed files
84+
*.sage.py
85+
86+
# Environments
87+
.env
88+
.venv
89+
env/
90+
venv/
91+
ENV/
92+
env.bak/
93+
venv.bak/
94+
95+
# Spyder project settings
96+
.spyderproject
97+
.spyproject
98+
99+
# Rope project settings
100+
.ropeproject
101+
102+
# mkdocs documentation
103+
/site
104+
105+
# mypy
106+
.mypy_cache/
107+

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Aidas Bendoraitis
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Experiment with Django and Elasticsearch
2+
3+
This Django project explores the possibilities of full-text search and filtering using Elasticsearch.
4+
5+
## Dependencies
6+
7+
The project depends on:
8+
9+
- Django >=1.8
10+
- Elasticsearch 5.6 - Server
11+
- elasticsearch v5.5.1 - Python Elasticsearch Client
12+
- elasticsearch-dsl v5.4.0 - Higher level library for the search queries
13+
- django-elasticsearch-dsl v0.4.4 - Integration with Django package
14+
- several other modules listed in the requirements.txt
15+
16+
## Quickstart
17+
18+
1. Install and run Elasticsearch server. For example on macOS:
19+
20+
```
21+
$ brew install [email protected]
22+
$ brew services start [email protected]
23+
```
24+
25+
2. Create and activate a virtual environment:
26+
27+
```
28+
$ virtualenv venv
29+
$ . venv/bin/activate
30+
```
31+
32+
3. Clone this project
33+
34+
4. Install pip requirements into the virtual environment:
35+
36+
```
37+
(venv)$ pip install -r requirements.txt
38+
```
39+
40+
5. Build the search index for the database:
41+
42+
```
43+
(venv)$ python manage.py search_index --rebuild
44+
```
45+
46+
6. Run local webserver:
47+
48+
```
49+
(venv)$ python manage.py runserver
50+
```
51+
52+
7. Open http://127.0.0.1:8000 to play around with the search.

db.sqlite3

160 KB
Binary file not shown.

library/__init__.py

Whitespace-only changes.

library/libraryapp/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# -*- coding: UTF-8 -*-
2+
from __future__ import unicode_literals
3+
4+
default_app_config = 'library.libraryapp.apps.LibraryAppConfig'

library/libraryapp/admin.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -*- coding: UTF-8 -*-
2+
from __future__ import unicode_literals
3+
from django.contrib import admin
4+
from django.utils.translation import ugettext_lazy as _
5+
6+
from .models import Author, Book
7+
8+
9+
@admin.register(Author)
10+
class AuthorAdmin(admin.ModelAdmin):
11+
save_on_top = True
12+
list_display = ["author_name"]
13+
list_filter = ["book"]
14+
search_fields = ["first_name", "last_name", "author_name"]
15+
fieldsets = [
16+
(_("Content"), {'fields': ["first_name", "last_name", "author_name"]}),
17+
]
18+
19+
20+
@admin.register(Book)
21+
class BookAdmin(admin.ModelAdmin):
22+
save_on_top = True
23+
list_display = ["title", "publishing_date"]
24+
list_filter = ["authors"]
25+
search_fields = ["title",]
26+
fieldsets = [
27+
(_("Content"), {'fields': ["title", "authors", "publishing_date"]}),
28+
]
29+
filter_horizontal = ["authors"]

library/libraryapp/apps.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: UTF-8 -*-
2+
from __future__ import unicode_literals
3+
from django.apps import AppConfig
4+
from django.utils.translation import ugettext_lazy as _
5+
6+
7+
class LibraryAppConfig(AppConfig):
8+
name = 'library.libraryapp'
9+
verbose_name = _("Library")
10+
11+
def ready(self):
12+
pass

library/libraryapp/documents.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# -*- coding: UTF-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django_elasticsearch_dsl import DocType, Index, fields
5+
from .models import Author, Book
6+
7+
# Name of the Elasticsearch index
8+
search_index = Index('library')
9+
# See Elasticsearch Indices API reference for available settings
10+
search_index.settings(
11+
number_of_shards=1,
12+
number_of_replicas=0
13+
)
14+
15+
16+
@search_index.doc_type
17+
class AuthorDocument(DocType):
18+
class Meta:
19+
model = Author # The model associated with this DocType
20+
21+
# The fields of the model you want to be indexed in Elasticsearch
22+
fields = [
23+
'first_name',
24+
'last_name',
25+
'author_name',
26+
]
27+
28+
# Ignore auto updating of Elasticsearch when a model is saved
29+
# or deleted:
30+
# ignore_signals = True
31+
# Don't perform an index refresh after every update (overrides global setting):
32+
# auto_refresh = False
33+
# Paginate the django queryset used to populate the index with the specified size
34+
# (by default there is no pagination)
35+
# queryset_pagination = 5000
36+
37+
38+
@search_index.doc_type
39+
class BookDocument(DocType):
40+
authors = fields.NestedField(properties={
41+
'first_name': fields.TextField(),
42+
'last_name': fields.TextField(),
43+
'author_name': fields.TextField(),
44+
'pk': fields.IntegerField(),
45+
}, include_in_root=True)
46+
47+
class Meta:
48+
model = Book # The model associated with this DocType
49+
50+
# The fields of the model you want to be indexed in Elasticsearch
51+
fields = [
52+
'title',
53+
'publishing_date',
54+
]
55+
related_models = [Author]
56+
57+
def get_instances_from_related(self, related_instance):
58+
"""If related_models is set, define how to retrieve the Book instance(s) from the related model."""
59+
if isinstance(related_instance, Author):
60+
return related_instance.book_set.all()

library/libraryapp/helpers.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: UTF-8 -*-
2+
from __future__ import unicode_literals
3+
from django import forms
4+
from django.utils.functional import LazyObject
5+
6+
7+
class SearchResults(LazyObject):
8+
def __init__(self, search_object):
9+
self._wrapped = search_object
10+
11+
def __len__(self):
12+
return self._wrapped.count()
13+
14+
def __getitem__(self, index):
15+
search_results = self._wrapped[index]
16+
if isinstance(index, slice):
17+
search_results = list(search_results)
18+
return search_results
19+
20+
21+
class DateInput(forms.DateInput):
22+
input_type = 'date'

0 commit comments

Comments
 (0)