├── elasticsearchproject ├── __init__.py ├── __pycache__ │ ├── urls.cpython-35.pyc │ ├── wsgi.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ └── settings.cpython-35.pyc ├── wsgi.py ├── urls.py └── settings.py ├── elasticsearchapp ├── migrations │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-35.pyc │ │ └── 0001_initial.cpython-35.pyc │ └── 0001_initial.py ├── __init__.py ├── tests.py ├── views.py ├── __pycache__ │ ├── admin.cpython-35.pyc │ ├── apps.cpython-35.pyc │ ├── models.cpython-35.pyc │ ├── search.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ └── signals.cpython-35.pyc ├── apps.py ├── admin.py ├── signals.py ├── models.py └── search.py ├── .DS_Store ├── db.sqlite3 ├── requirements.txt ├── .idea ├── encodings.xml ├── vcs.xml ├── modules.xml ├── elasticsearchproject.iml ├── misc.xml └── workspace.xml ├── README.md └── manage.py /elasticsearchproject/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /elasticsearchapp/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/.DS_Store -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/db.sqlite3 -------------------------------------------------------------------------------- /elasticsearchapp/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = 'elasticsearchapp.apps.ElasticsearchappConfig' -------------------------------------------------------------------------------- /elasticsearchapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /elasticsearchapp/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==3.2.18 2 | elasticsearch==7.15.0 3 | elasticsearch-dsl==7.4.0 4 | python-dateutil==2.8.2 5 | six==1.16.0 6 | urllib3==1.26.7 7 | -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/admin.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/admin.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/apps.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/apps.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/models.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/models.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/search.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/search.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/__pycache__/signals.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/__pycache__/signals.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchproject/__pycache__/urls.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchproject/__pycache__/urls.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchproject/__pycache__/wsgi.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchproject/__pycache__/wsgi.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchproject/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchproject/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchproject/__pycache__/settings.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchproject/__pycache__/settings.cpython-35.pyc -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /elasticsearchapp/migrations/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/migrations/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /elasticsearchapp/migrations/__pycache__/0001_initial.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamwattis/elasticsearch-example/HEAD/elasticsearchapp/migrations/__pycache__/0001_initial.cpython-35.pyc -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /elasticsearchapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ElasticsearchappConfig(AppConfig): 5 | name = 'elasticsearchapp' 6 | 7 | def ready(self): 8 | import elasticsearchapp.signals -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elasticsearch-example 2 | Simple example using ElasticSearch with Django 3 | 4 | Link to Medium article. 5 | -------------------------------------------------------------------------------- /elasticsearchapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import BlogPost 3 | 4 | # Register your models here. 5 | 6 | # Need to register my BlogPost so it shows up in the admin 7 | admin.site.register(BlogPost) -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "elasticsearchproject.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /elasticsearchapp/signals.py: -------------------------------------------------------------------------------- 1 | from .models import BlogPost 2 | from django.db.models.signals import post_save 3 | from django.dispatch import receiver 4 | 5 | 6 | # Signal to save each new blog post instance into ElasticSearch 7 | @receiver(post_save, sender=BlogPost) 8 | def index_post(sender, instance, **kwargs): 9 | print(instance) 10 | instance.indexing() 11 | -------------------------------------------------------------------------------- /.idea/elasticsearchproject.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /elasticsearchproject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for elasticsearchproject project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "elasticsearchproject.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /elasticsearchproject/urls.py: -------------------------------------------------------------------------------- 1 | """elasticsearchproject URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | 19 | urlpatterns = [ 20 | url(r'^admin/', admin.site.urls), 21 | ] 22 | -------------------------------------------------------------------------------- /elasticsearchapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils import timezone 3 | from django.contrib.auth.models import User 4 | from .search import BlogPostIndex 5 | 6 | # Create your models here. 7 | 8 | # Blogpost to be indexed into ElasticSearch 9 | 10 | 11 | class BlogPost(models.Model): 12 | author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blogpost') 13 | posted_date = models.DateField(default=timezone.now) 14 | title = models.CharField(max_length=200) 15 | text = models.TextField(max_length=1000) 16 | 17 | # Method for indexing the model 18 | def indexing(self): 19 | obj = BlogPostIndex( 20 | meta={'id': self.id}, 21 | author=self.author.username, 22 | posted_date=self.posted_date, 23 | title=self.title, 24 | text=self.text 25 | ) 26 | obj.save() 27 | return obj.to_dict(include_meta=True) 28 | -------------------------------------------------------------------------------- /elasticsearchapp/search.py: -------------------------------------------------------------------------------- 1 | from elasticsearch_dsl.connections import connections 2 | from elasticsearch_dsl import Document, Text, Date, Search 3 | from elasticsearch.helpers import bulk 4 | from elasticsearch import Elasticsearch 5 | from . import models 6 | 7 | # Create a connection to ElasticSearch 8 | connections.create_connection() 9 | 10 | # ElasticSearch "model" mapping out what fields to index 11 | class BlogPostIndex(Document): 12 | author = Text() 13 | posted_date = Date() 14 | title = Text() 15 | text = Text() 16 | 17 | class Index: 18 | name = 'blogpost-index' 19 | 20 | # Bulk indexing function, run in shell 21 | def bulk_indexing(): 22 | BlogPostIndex.init() 23 | es = Elasticsearch() 24 | bulk(client=es, actions=(b.indexing() for b in models.BlogPost.objects.all().iterator())) 25 | 26 | # Simple search function 27 | def search(author): 28 | s = Search().filter('term', author=author) 29 | response = s.execute() 30 | return response 31 | -------------------------------------------------------------------------------- /elasticsearchapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.5 on 2017-01-07 02:06 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | import django.utils.timezone 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | initial = True 14 | 15 | dependencies = [ 16 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 17 | ] 18 | 19 | operations = [ 20 | migrations.CreateModel( 21 | name='BlogPost', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('posted_date', models.DateField(default=django.utils.timezone.now)), 25 | ('title', models.CharField(max_length=200)), 26 | ('text', models.TextField(max_length=1000)), 27 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='blogpost', to=settings.AUTH_USER_MODEL)), 28 | ], 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /elasticsearchproject/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for elasticsearchproject project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.9.4. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.9/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '0_z8$vlv0xgke(eay6$&(-v_f)=+-yu@yrt8=yw2aej3=cyxg&' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'elasticsearchapp', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'elasticsearchproject.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'elasticsearchproject.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 118 | 119 | 128 | 129 | 130 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 167 | 168 | 169 | 170 | 173 | 174 | 177 | 178 | 179 | 180 | 183 | 184 | 187 | 188 | 191 | 192 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 218 | 219 | 220 | 221 | 1483723824363 222 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 255 | 258 | 259 | 260 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | --------------------------------------------------------------------------------