=============================
Django Elastic App Search
=============================
.. image:: https://badge.fury.io/py/django-elastic-appsearch.svg
:target: https://badge.fury.io/py/django-elastic-appsearch
.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Tests/badge.svg
:target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ATests
.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Lint/badge.svg
:target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ALint
.. image:: https://codecov.io/gh/infoxchange/django_elastic_appsearch/branch/master/graph/badge.svg
:target: https://codecov.io/gh/infoxchange/django_elastic_appsearch
.. image:: https://readthedocs.org/projects/django-elastic-appsearch/badge/?version=latest
:target: https://django-elastic-appsearch.readthedocs.io/en/latest/?badge=latest
.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Dependencies/badge.svg
:target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ADependencies
Integrate your Django Project with Elastic App Search with ease.
Documentation
-------------
The full documentation is at https://django_elastic_appsearch.readthedocs.io. Read our step-by-step guide on integrating App Search with your existing Django project over at Medium_.
.. _Medium: https://medium.com/@rasika.am/integrating-a-django-project-with-elastic-app-search-fb9f16726b5c
Dependencies
------------
* Python >= 3.6
* Django >= 2.2
* `elastic-enterprise-search <https://pypi.org/project/elastic-enterprise-search/>`_
* `serpy <https://pypi.org/project/serpy/>`_
Usage
-----
Installing
==========
Install Django Elastic App Search::
pip install django_elastic_appsearch
Add it to your `INSTALLED_APPS`:
.. code-block:: python
INSTALLED_APPS = (
...
'django_elastic_appsearch',
...
)
Add the Elastic App Search URL and Key to your settings module:
.. code-block:: python
APPSEARCH_HOST = 'localhost:3002'
APPSEARCH_API_KEY = 'some_appsearch_api_token'
Configuring app search indexable models
=======================================
Single engine
=============
Configure the Django models you want to index to Elastic App Search. To index to one engine you can do this by inheriting from the ``AppSearchModel``, and then setting some meta options.
``AppsearchMeta.appsearch_engine_name`` - Defines which engine in your app search instance your model will be indexed to.
``AppsearchMeta.appsearch_serialiser_class`` - Defines how your model object will be serialised when sent to your elastic app search instance. The serialiser and fields used here derives from `Serpy <https://serpy.readthedocs.io/>`__, and you can use any of the serpy features like method fields.
Example:
.. code-block:: python
from django_elastic_appsearch.orm import AppSearchModel
from django_elastic_appsearch import serialisers
class CarSerialiser(serialisers.AppSearchSerialiser):
full_name = serialisers.MethodField()
make = serialisers.StrField()
model = serialisers.StrField()
manufactured_year = serialisers.Field()
def get_full_name(self, instance):
return '{} {}'.format(make, model)
class Car(AppSearchModel):
class AppsearchMeta:
appsearch_engine_name = 'cars'
appsearch_serialiser_class = CarSerialiser
make = models.CharField(max_length=100)
model = models.CharField(max_length=100)
manufactured_year = models.CharField(max_length=4)
Multi engine
============
Configure the Django models you want to index to Elastic App Search. To index to multiple engines you can do this by inheriting from the ``AppSearchMultiEngineModel``,
and then setting a meta option.
``AppsearchMeta.appsearch_serialiser_engine_pairs`` - A list of tuples of serialisers then engines that define which engine in your app search instance your model will
be indexed to and how your model object will be serialised when sent to your elastic app search instance. The serialiser and fields used here derives from
`Serpy <https://serpy.readthedocs.io/>`__, and you can use any of the serpy features like method fields.
Example:
.. code-block:: python
from django_elastic_appsearch.orm import AppSearchModel
from django_elastic_appsearch import serialisers
class CarSerialiser(serialisers.AppSearchSerialiser):
full_name = serialisers.MethodField()
make = serialisers.StrField()
model = serialisers.StrField()
manufactured_year = serialisers.Field()
def get_full_name(self, instance):
return '{} {}'.format(make, model)
class Truck(AppSearchMultiEngineModel):
"""A truck."""
class AppsearchMeta:
appsearch_serialiser_engine_pairs = [(CarSerialiser, "trucks")]
make = models.TextField()
model = models.TextField()
year_manufactured = models.DateTimeField()
Using model and queryset methods to index and delete documents
==============================================================
Then you can call ``index_to_appsearch`` and ``delete_from_appsearch`` from your model objects.
Send the car with id 25 to app search.
.. code-block:: python
from mymodels import Car
car = Car.objects.get(id=25)
car.index_to_appsearch()
Delete the car with id 21 from app search.
.. code-block:: python
from mymodels import Car
car = Car.objects.get(id=21)
car.delete_from_appsearch()
Calling these on an ``AppSearchModel`` will return a single response object, and calling them on an ``AppSearchMultiEngineModel`` will return a list of response objects.
You can also call ``index_to_appsearch`` and ``delete_from_appsearch`` on QuerySets of ``AppSearchModel``
Send all cars where the make is 'Toyota' to app search.
.. code-block:: python
cars = Car.objects.filter(make='Toyota')
cars.index_to_appsearch()
Delete all cars where the make is 'Saab' from app search
.. code-block:: python
cars = Car.objects.filter(make='Saab')
cars.delete_from_appsearch()
``index_to_appsearch`` methods on the QuerySet and your model also supports an optional ``update_only`` parameter which takes in a boolean value. If ``update_only`` is set to ``True``, the operation on the app search instance will be carried out as a ``PATCH`` operation. This will be useful if your Django application is only doing partial updates to the documents.
This will also mean that your serialisers can contain a subset of the fields for a document. This will be useful when two or more Django models or applications are using the same app search engine to update different sets of fields on a single document type.
Example below (Continued from the above ``Car`` example):
.. code-block:: python
from django.db import models
from django_elastic_appsearch.orm import AppSearchModel
from django_elastic_appsearch import serialisers
class CarVINNumberSerialiser(serialisers.AppSearchSerialiser):
vin_number = serialisers.StrField()
class CarVINNumber(AppSearchModel):
class AppsearchMeta:
appsearch_engine_name = 'cars'
appsearch_serialiser_class = CarVINNumberSerialiser
car = models.OneToOneField(
Car,
on_delete=models.CASCADE,
primary_key=True
)
vin_number = models.CharField(max_length=100)
def get_appsearch_document_id(self):
return 'Car_{}'.format(self.car.id)
.. code-block:: python
from mymodels import CarVINNumber
car_vin = CarVINNumber.objects.filter('car__id'=25).first()
car_vin.vin_number = '1M8GDM9A_KP042788'
car_vin.save()
car_vin.refresh_from_db()
car_vin.index_to_appsearch(update_only=True)
You'll notice that we've set the ``appsearch_engine_name`` to ``cars`` so that the VIN number updates will go through to the same engine. You'll also notice that we've overridden the ``get_appsearch_document_id`` method to make sure that VIN number updates do go through the same related car document.
The above example will update the car document with id 25 with the new VIN number and leave the data for the rest of the fields intact.
Important note: ``PATCH`` operations on Elastic App Search cannot create new schema fields if you submit schema fields currently unknown to your engine. So always make sure you're submitting values for existing schema fields on your engine.
Use with your own custom queryset managers
==========================================
If you want to specify custom managers which also has this functionality, you can inherit from ``django_elastic_appsearch.orm.AppSearchQuerySet``
.. code-block:: python
from django_elastic_appsearch.orm import AppSearchModel, AppSearchQuerySet
class MyCustomQuerySetManager(AppSearchQuerySet):
def my_custom_queryset_feature(self):
# Do Something cool
pass
class MyCustomModel(AppSearchModel):
field_1 = models.CharField(max_length=100)
# Set the custom manager
objects = MyCustomQuerySetManager.as_manager()
Use a custom document id for appsearch
==========================================
By default, the unique document ID which identifies your model objects in app search is set to ``<model_name>_<object_id>``. If we take the car example above, a ``Car`` object with an id of ``543`` will have the document ID ``Car_543`` in app search.
You can customise this value by overriding the ``get_appsearch_document_id`` method on your model class.
Eg. You can do the following to make sure that the document ID on appsearch is exactly the same as the ID on your model object.
.. code-block:: python
class Car(AppSearchModel):
class AppsearchMeta:
appsearch_engine_name = 'cars'
appsearch_serialiser_class = CarSerialiser
make = models.CharField(max_length=100)
model = models.CharField(max_length=100)
manufactured_year = models.CharField(max_length=4)
def get_appsearch_document_id(self):
return self.id
Settings
========
This package provides various Django settings entries you can use to configure your connection to the Elastic App Search instance you're using.
APPSEARCH_HOST
^^^^^^^^^^^^^^
* Required: Yes
* Default: No default value
This is a **required** setting to tell your Django application which Elastic App Search instance to connect with.
.. code-block:: python
APPSEARCH_HOST = 'localhost:3002'
APPSEARCH_API_KEY
^^^^^^^^^^^^^^^^^
* Required: Yes
* Default: No default value
This is a **required** setting to tell your Django application the private key to use to talk to your Elastic App Search instance.
.. code-block:: python
APPSEARCH_API_KEY = 'private-key'
APPSEARCH_USE_HTTPS
^^^^^^^^^^^^^^^^^^^
* Required: No
* Default: ``True``
This is an **optional** setting to configure whether to use HTTPS or not when your Django application communicates with your Elastic App Search instances. It defaults to ``True`` if it's not set. This might be useful when you're running your Django project against a local Elastic App Search instance. It's insecure to have this as ``False`` in a production environment, so make sure to change to ``True`` in your production version.
.. code-block:: python
APPSEARCH_USE_HTTPS = False
APPSEARCH_CHUNK_SIZE
^^^^^^^^^^^^^^^^^^^^
* Required: No
* Default: ``100``
This is an **optional** setting to configure the chunk size when doing queryset indexing/deleting. Elastic App Search supports upto a 100 documents in one index/destroy request. With this setting, you can change it to your liking. It defaults to the maximum of ``100`` when this is not set. This might be useful when you want to reduce the size of a request to your Elastic App Search instance when your documents have a lot of fields/data.
.. code-block:: python
APPSEARCH_CHUNK_SIZE = 50
APPSEARCH_INDEXING_ENABLED
^^^^^^^^^^^^^^^^^^^^^^^^^^
* Required: No
* Default: ``True``
This is an **optional** setting to configure if you want to disable indexing to your Elastic App Search instance. This is useful when you want to disable indexing without changing any code. When it's set to ``False``, any code where you use ``index_to_appsearch()`` or ``delete_from_appsearch()`` will not do anything. It's set to ``True`` by default when it's not set.
.. code-block:: python
APPSEARCH_INDEXING_ENABLED = True
Example with all settings entries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
APPSEARCH_HOST = 'localhost:3002'
APPSEARCH_API_KEY = 'private-key'
APPSEARCH_USE_HTTPS = False
APPSEARCH_CHUNK_SIZE = 50
APPSEARCH_INDEXING_ENABLED = True
Writing Tests
=============
This package provides a test case mixin called ``MockedAppSearchTestCase`` which makes it easier for you to write test cases against ``AppSearchModel``'s and ``AppSearchMultiEngineModel``'s without actually having to run an Elastic App Search instance during tests.
All you have to do is inherit the mixin, and all the calls to Elastic App Search will be mocked. Example below.
.. code-block:: python
from django.test import TestCase
from django_elastic_appsearch.test import MockedAppSearchTestCase
from myapp.test.factories import CarFactory
class BookTestCase(MockedAppSearchTestCase, TestCase):
def test_indexing_book(self):
car = CarFactory()
car.save()
car.index_to_appsearch()
self.assertAppSearchModelIndexCallCount(1)
You will have access to the following methods to check call counts to different mocked app search methods.
``self.assertAppSearchQuerySetIndexCallCount`` — Check the number of times index_to_appsearch was called on a appsearch model querysets.
``self.assertAppSearchQuerySetDeleteCallCount`` — Check the number of times delete_from_appsearch was called on an appsearch model querysets.
``self.assertAppSearchModelIndexCallCount`` — Check the number of times index_to_appsearch was called on an appsearch model objects.
``self.assertAppSearchModelDeleteCallCount`` — Check the number of times delete_from_appsearch was called on an appsearch model objects.
If you are using a subclass of `AppSearchQuerySet` that overrides methods without calling the super class version you can use the `queryset_class` key word argument to the `setUp` function to mock it. Example below.
.. code-block:: python
from django.test import TestCase
from django_elastic_appsearch.test import MockedAppSearchTestCase
class BusTestCase(MockedAppSearchTestCase, TestCase):
"""Test the `MockedAppSearchTestCase`."""
def setUp(self, *args, **kwargs):
"""Load test data."""
kwargs['queryset_class'] = 'example.querysets.CustomQuerySet.'
super().setUp(*args, **kwargs)
Using the elastic app search python client
==========================================
We use the official `elastic app search python client <https://github.com/elastic/enterprise-search-python>`_ under the hood to communicate with the app search instance. So if needed, you can access the app search instance directly and use the functionality of the official elastic app search `client <https://github.com/elastic/enterprise-search-python#usage>`_. Example below.
.. code-block:: python
from django_elastic_appsearch.clients import get_api_v1_enterprise_search_client
client = get_api_v1_enterprise_search_client()
client.search('cars', 'Toyota Corolla', {})
Contributing
------------
Contributors are welcome!
* Prior to opening a pull request, please create an issue to discuss the change/feature you've written/thinking of writing if it doesn't already exist.
* Please write simple code and concise documentation, when appropriate.
* Please write test cases to cover the code you've written, where possible.
* Read the `Contributing <https://django-elastic-appsearch.readthedocs.io/en/latest/contributing.html#>`_ section of our documentation for more information around contributing to this project.
Running Tests
-------------
Does the code actually work?
::
$ pipenv install --dev
$ pipenv shell
(django_elastic_appsearch) $ tox
Credits
-------
Tools used in rendering this package:
* Cookiecutter_
* `cookiecutter-djangopackage`_
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage
History
-------
1.1.5 (2021-05-11)
===================
* Transfer ownership to Infoxchange
* Update documentation
* Dependency upgrades
1.1.4 (2021-05-05)
===================
* Updated documentation
* Dependency upgrades
1.1.3 (2021-04-12)
===================
* Add Django 3.2 to the test matrix
* Dependency upgrades
* Minor fixes
1.1.2 (2021-02-11)
===================
* Security patch
1.1.1 (2021-02-04)
===================
* Dependency upgrades
* Security patch
* Improve returned responses
1.1.0 (2021-01-27)
===================
* Dependecy upgrades
* Add ability to index a model object into multiple app search engines
1.0.2 (2020-12-29)
===================
* Dependency upgrades
1.0.1 (2020-12-15)
===================
* Dependency upgrades
1.0.0 (2020-11-26)
===================
* Python 3.9 support
* Update the project status to stable
0.7.6 (2020-11-26)
===================
* Dependency upgrades
* Update documentation
0.7.5 (2020-10-28)
===================
* Security patch
0.7.4 (2020-10-05)
===================
* Add support for testing overridden queryset methods
* Update documentation
0.7.3 (2020-08-25)
===================
* Remove support for Django 2.0 and Django 2.1
* Add support for Django 3.1
* Update documentation
0.7.2 (2020-08-25)
===================
* Dependency upgrades
0.7.1 (2020-07-31)
===================
* Dependency upgrades
0.7.0 (2020-07-30)
===================
* Implement ability to do partial updates to documents
* Dependency upgrades
0.6.11 (2020-06-22)
===================
* Fix failing dependency check with pipenv
* Dependency upgrades
0.6.9 (2020-05-15)
==================
* Dependency upgrades
0.6.8 (2020-03-31)
==================
* Dependency upgrades
* Security patches
0.6.7 (2020-02-25)
==================
* Dependency upgrades
0.6.6 (2020-02-01)
==================
* Dependency upgrades
0.6.3 (2020-01-03)
==================
* Move from Travis CI to Github Actions
* Documentation updates
0.6.2 (2020-01-02)
==================
* Dependency upgrades
* Documentation improvements
* Add linting for CI
* Setup automatic PyPI releases
0.6.1 (2019-12-24)
==================
* Dependency upgrades
0.6.0 (2019-12-04)
==================
* Remove support for Python 3.5
* Add support for Python 3.8
* Add support for Django 3
* Dependency upgrades
* Bump development status to Beta
0.5.6 (2019-12-03)
==================
* Dependency upgrades
0.5.5 (2019-11-14)
==================
* Dependency upgrades
0.5.4 (2019-10-02)
==================
* Dependency upgrades
0.5.3 (2019-08-28)
==================
* Improve documentation
* Refactor settings name ``APPSEARCH_URL`` -> ``APPSEARCH_HOST``
0.5.1 (2019-08-26)
==================
* Improve test coverage
* Improve documentation
* Add serpy as an official dependency
* Bump dependency versions
* Add code of conduct
0.4.2 (2019-08-16)
==================
* Switch to the new official Elastic App Search python client
* Documentation improvements
0.2.3 (2019-08-02)
==================
* Use Pipenv for dependency management
* Configure Dependabot for automatic dependency upgrades
* Remove support for Python 3.4
* Documentation improvements
0.2.2 (2019-07-29)
==================
* Bug fixes
* Documentation improvements
0.1.0 (2019-07-26)
==================
* First release on PyPI.
Raw data
{
"_id": null,
"home_page": "https://github.com/infoxchange/django_elastic_appsearch",
"name": "django-elastic-appsearch",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "django_elastic_appsearch",
"author": "Infoxchange",
"author_email": "devs@infoxchange.org",
"download_url": "https://files.pythonhosted.org/packages/e8/eb/d259e5f898e9fc239b15ceb3742883918f684933f5f6b5bd356d89558dcc/django_elastic_appsearch-2.1.0.tar.gz",
"platform": null,
"description": "=============================\nDjango Elastic App Search\n=============================\n\n.. image:: https://badge.fury.io/py/django-elastic-appsearch.svg\n :target: https://badge.fury.io/py/django-elastic-appsearch\n\n.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Tests/badge.svg\n :target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ATests\n\n.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Lint/badge.svg\n :target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ALint\n\n.. image:: https://codecov.io/gh/infoxchange/django_elastic_appsearch/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/infoxchange/django_elastic_appsearch\n\n.. image:: https://readthedocs.org/projects/django-elastic-appsearch/badge/?version=latest\n :target: https://django-elastic-appsearch.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://github.com/corrosivekid/django_elastic_appsearch/workflows/Dependencies/badge.svg\n :target: https://github.com/CorrosiveKid/django_elastic_appsearch/actions?query=workflow%3ADependencies\n\nIntegrate your Django Project with Elastic App Search with ease.\n\nDocumentation\n-------------\n\nThe full documentation is at https://django_elastic_appsearch.readthedocs.io. Read our step-by-step guide on integrating App Search with your existing Django project over at Medium_.\n\n.. _Medium: https://medium.com/@rasika.am/integrating-a-django-project-with-elastic-app-search-fb9f16726b5c\n\nDependencies\n------------\n\n* Python >= 3.6\n* Django >= 2.2\n* `elastic-enterprise-search <https://pypi.org/project/elastic-enterprise-search/>`_\n* `serpy <https://pypi.org/project/serpy/>`_\n\nUsage\n-----\nInstalling\n==========\n\nInstall Django Elastic App Search::\n\n pip install django_elastic_appsearch\n\nAdd it to your `INSTALLED_APPS`:\n\n.. code-block:: python\n\n INSTALLED_APPS = (\n ...\n 'django_elastic_appsearch',\n ...\n )\n\nAdd the Elastic App Search URL and Key to your settings module:\n\n.. code-block:: python\n\n APPSEARCH_HOST = 'localhost:3002'\n APPSEARCH_API_KEY = 'some_appsearch_api_token'\n\nConfiguring app search indexable models\n=======================================\n\nSingle engine\n=============\n\nConfigure the Django models you want to index to Elastic App Search. To index to one engine you can do this by inheriting from the ``AppSearchModel``, and then setting some meta options.\n\n``AppsearchMeta.appsearch_engine_name`` - Defines which engine in your app search instance your model will be indexed to.\n\n``AppsearchMeta.appsearch_serialiser_class`` - Defines how your model object will be serialised when sent to your elastic app search instance. The serialiser and fields used here derives from `Serpy <https://serpy.readthedocs.io/>`__, and you can use any of the serpy features like method fields.\n\nExample:\n\n.. code-block:: python\n\n from django_elastic_appsearch.orm import AppSearchModel\n from django_elastic_appsearch import serialisers\n\n class CarSerialiser(serialisers.AppSearchSerialiser):\n full_name = serialisers.MethodField()\n make = serialisers.StrField()\n model = serialisers.StrField()\n manufactured_year = serialisers.Field()\n\n def get_full_name(self, instance):\n return '{} {}'.format(make, model)\n\n\n class Car(AppSearchModel):\n\n class AppsearchMeta:\n appsearch_engine_name = 'cars'\n appsearch_serialiser_class = CarSerialiser\n\n make = models.CharField(max_length=100)\n model = models.CharField(max_length=100)\n manufactured_year = models.CharField(max_length=4)\n\nMulti engine\n============\n\nConfigure the Django models you want to index to Elastic App Search. To index to multiple engines you can do this by inheriting from the ``AppSearchMultiEngineModel``,\nand then setting a meta option.\n\n``AppsearchMeta.appsearch_serialiser_engine_pairs`` - A list of tuples of serialisers then engines that define which engine in your app search instance your model will\nbe indexed to and how your model object will be serialised when sent to your elastic app search instance. The serialiser and fields used here derives from\n`Serpy <https://serpy.readthedocs.io/>`__, and you can use any of the serpy features like method fields.\n\nExample:\n\n.. code-block:: python\n\n from django_elastic_appsearch.orm import AppSearchModel\n from django_elastic_appsearch import serialisers\n\n class CarSerialiser(serialisers.AppSearchSerialiser):\n full_name = serialisers.MethodField()\n make = serialisers.StrField()\n model = serialisers.StrField()\n manufactured_year = serialisers.Field()\n\n def get_full_name(self, instance):\n return '{} {}'.format(make, model)\n\n\n class Truck(AppSearchMultiEngineModel):\n \"\"\"A truck.\"\"\"\n\n class AppsearchMeta:\n appsearch_serialiser_engine_pairs = [(CarSerialiser, \"trucks\")]\n\n make = models.TextField()\n model = models.TextField()\n year_manufactured = models.DateTimeField()\n\nUsing model and queryset methods to index and delete documents\n==============================================================\n\nThen you can call ``index_to_appsearch`` and ``delete_from_appsearch`` from your model objects.\n\nSend the car with id 25 to app search.\n\n.. code-block:: python\n\n from mymodels import Car\n\n car = Car.objects.get(id=25)\n car.index_to_appsearch()\n\nDelete the car with id 21 from app search.\n\n.. code-block:: python\n\n from mymodels import Car\n\n car = Car.objects.get(id=21)\n car.delete_from_appsearch()\n\nCalling these on an ``AppSearchModel`` will return a single response object, and calling them on an ``AppSearchMultiEngineModel`` will return a list of response objects.\n\nYou can also call ``index_to_appsearch`` and ``delete_from_appsearch`` on QuerySets of ``AppSearchModel``\n\nSend all cars where the make is 'Toyota' to app search.\n\n.. code-block:: python\n\n cars = Car.objects.filter(make='Toyota')\n cars.index_to_appsearch()\n\nDelete all cars where the make is 'Saab' from app search\n\n.. code-block:: python\n\n cars = Car.objects.filter(make='Saab')\n cars.delete_from_appsearch()\n\n``index_to_appsearch`` methods on the QuerySet and your model also supports an optional ``update_only`` parameter which takes in a boolean value. If ``update_only`` is set to ``True``, the operation on the app search instance will be carried out as a ``PATCH`` operation. This will be useful if your Django application is only doing partial updates to the documents.\n\nThis will also mean that your serialisers can contain a subset of the fields for a document. This will be useful when two or more Django models or applications are using the same app search engine to update different sets of fields on a single document type.\n\nExample below (Continued from the above ``Car`` example):\n\n.. code-block:: python\n\n from django.db import models\n from django_elastic_appsearch.orm import AppSearchModel\n from django_elastic_appsearch import serialisers\n\n class CarVINNumberSerialiser(serialisers.AppSearchSerialiser):\n vin_number = serialisers.StrField()\n\n class CarVINNumber(AppSearchModel):\n\n class AppsearchMeta:\n appsearch_engine_name = 'cars'\n appsearch_serialiser_class = CarVINNumberSerialiser\n\n car = models.OneToOneField(\n Car,\n on_delete=models.CASCADE,\n primary_key=True\n )\n vin_number = models.CharField(max_length=100)\n\n def get_appsearch_document_id(self):\n return 'Car_{}'.format(self.car.id)\n\n.. code-block:: python\n\n from mymodels import CarVINNumber\n\n car_vin = CarVINNumber.objects.filter('car__id'=25).first()\n car_vin.vin_number = '1M8GDM9A_KP042788'\n car_vin.save()\n car_vin.refresh_from_db()\n car_vin.index_to_appsearch(update_only=True)\n\nYou'll notice that we've set the ``appsearch_engine_name`` to ``cars`` so that the VIN number updates will go through to the same engine. You'll also notice that we've overridden the ``get_appsearch_document_id`` method to make sure that VIN number updates do go through the same related car document.\n\nThe above example will update the car document with id 25 with the new VIN number and leave the data for the rest of the fields intact.\n\nImportant note: ``PATCH`` operations on Elastic App Search cannot create new schema fields if you submit schema fields currently unknown to your engine. So always make sure you're submitting values for existing schema fields on your engine.\n\nUse with your own custom queryset managers\n==========================================\n\nIf you want to specify custom managers which also has this functionality, you can inherit from ``django_elastic_appsearch.orm.AppSearchQuerySet``\n\n.. code-block:: python\n\n from django_elastic_appsearch.orm import AppSearchModel, AppSearchQuerySet\n\n class MyCustomQuerySetManager(AppSearchQuerySet):\n def my_custom_queryset_feature(self):\n # Do Something cool\n pass\n\n class MyCustomModel(AppSearchModel):\n field_1 = models.CharField(max_length=100)\n\n # Set the custom manager\n objects = MyCustomQuerySetManager.as_manager()\n\nUse a custom document id for appsearch\n==========================================\n\nBy default, the unique document ID which identifies your model objects in app search is set to ``<model_name>_<object_id>``. If we take the car example above, a ``Car`` object with an id of ``543`` will have the document ID ``Car_543`` in app search.\n\nYou can customise this value by overriding the ``get_appsearch_document_id`` method on your model class.\n\nEg. You can do the following to make sure that the document ID on appsearch is exactly the same as the ID on your model object.\n\n.. code-block:: python\n\n class Car(AppSearchModel):\n\n class AppsearchMeta:\n appsearch_engine_name = 'cars'\n appsearch_serialiser_class = CarSerialiser\n\n make = models.CharField(max_length=100)\n model = models.CharField(max_length=100)\n manufactured_year = models.CharField(max_length=4)\n\n def get_appsearch_document_id(self):\n return self.id\n\nSettings\n========\n\nThis package provides various Django settings entries you can use to configure your connection to the Elastic App Search instance you're using.\n\nAPPSEARCH_HOST\n^^^^^^^^^^^^^^\n\n* Required: Yes\n* Default: No default value\n\nThis is a **required** setting to tell your Django application which Elastic App Search instance to connect with.\n\n.. code-block:: python\n\n APPSEARCH_HOST = 'localhost:3002'\n\nAPPSEARCH_API_KEY\n^^^^^^^^^^^^^^^^^\n\n* Required: Yes\n* Default: No default value\n\nThis is a **required** setting to tell your Django application the private key to use to talk to your Elastic App Search instance.\n\n.. code-block:: python\n\n APPSEARCH_API_KEY = 'private-key'\n\nAPPSEARCH_USE_HTTPS\n^^^^^^^^^^^^^^^^^^^\n\n* Required: No\n* Default: ``True``\n\nThis is an **optional** setting to configure whether to use HTTPS or not when your Django application communicates with your Elastic App Search instances. It defaults to ``True`` if it's not set. This might be useful when you're running your Django project against a local Elastic App Search instance. It's insecure to have this as ``False`` in a production environment, so make sure to change to ``True`` in your production version.\n\n.. code-block:: python\n\n APPSEARCH_USE_HTTPS = False\n\nAPPSEARCH_CHUNK_SIZE\n^^^^^^^^^^^^^^^^^^^^\n\n* Required: No\n* Default: ``100``\n\nThis is an **optional** setting to configure the chunk size when doing queryset indexing/deleting. Elastic App Search supports upto a 100 documents in one index/destroy request. With this setting, you can change it to your liking. It defaults to the maximum of ``100`` when this is not set. This might be useful when you want to reduce the size of a request to your Elastic App Search instance when your documents have a lot of fields/data.\n\n.. code-block:: python\n\n APPSEARCH_CHUNK_SIZE = 50\n\nAPPSEARCH_INDEXING_ENABLED\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n* Required: No\n* Default: ``True``\n\nThis is an **optional** setting to configure if you want to disable indexing to your Elastic App Search instance. This is useful when you want to disable indexing without changing any code. When it's set to ``False``, any code where you use ``index_to_appsearch()`` or ``delete_from_appsearch()`` will not do anything. It's set to ``True`` by default when it's not set.\n\n.. code-block:: python\n\n APPSEARCH_INDEXING_ENABLED = True\n\nExample with all settings entries\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n APPSEARCH_HOST = 'localhost:3002'\n APPSEARCH_API_KEY = 'private-key'\n APPSEARCH_USE_HTTPS = False\n APPSEARCH_CHUNK_SIZE = 50\n APPSEARCH_INDEXING_ENABLED = True\n\nWriting Tests\n=============\n\nThis package provides a test case mixin called ``MockedAppSearchTestCase`` which makes it easier for you to write test cases against ``AppSearchModel``'s and ``AppSearchMultiEngineModel``'s without actually having to run an Elastic App Search instance during tests.\n\nAll you have to do is inherit the mixin, and all the calls to Elastic App Search will be mocked. Example below.\n\n.. code-block:: python\n\n from django.test import TestCase\n from django_elastic_appsearch.test import MockedAppSearchTestCase\n from myapp.test.factories import CarFactory\n\n class BookTestCase(MockedAppSearchTestCase, TestCase):\n def test_indexing_book(self):\n car = CarFactory()\n car.save()\n car.index_to_appsearch()\n\n self.assertAppSearchModelIndexCallCount(1)\n\nYou will have access to the following methods to check call counts to different mocked app search methods.\n\n``self.assertAppSearchQuerySetIndexCallCount`` \u2014 Check the number of times index_to_appsearch was called on a appsearch model querysets.\n\n``self.assertAppSearchQuerySetDeleteCallCount`` \u2014 Check the number of times delete_from_appsearch was called on an appsearch model querysets.\n\n``self.assertAppSearchModelIndexCallCount`` \u2014 Check the number of times index_to_appsearch was called on an appsearch model objects.\n\n``self.assertAppSearchModelDeleteCallCount`` \u2014 Check the number of times delete_from_appsearch was called on an appsearch model objects.\n\nIf you are using a subclass of `AppSearchQuerySet` that overrides methods without calling the super class version you can use the `queryset_class` key word argument to the `setUp` function to mock it. Example below.\n\n.. code-block:: python\n\n from django.test import TestCase\n from django_elastic_appsearch.test import MockedAppSearchTestCase\n\n class BusTestCase(MockedAppSearchTestCase, TestCase):\n \"\"\"Test the `MockedAppSearchTestCase`.\"\"\"\n\n def setUp(self, *args, **kwargs):\n \"\"\"Load test data.\"\"\"\n kwargs['queryset_class'] = 'example.querysets.CustomQuerySet.'\n super().setUp(*args, **kwargs)\n\n\nUsing the elastic app search python client\n==========================================\n\nWe use the official `elastic app search python client <https://github.com/elastic/enterprise-search-python>`_ under the hood to communicate with the app search instance. So if needed, you can access the app search instance directly and use the functionality of the official elastic app search `client <https://github.com/elastic/enterprise-search-python#usage>`_. Example below.\n\n.. code-block:: python\n\n from django_elastic_appsearch.clients import get_api_v1_enterprise_search_client\n\n client = get_api_v1_enterprise_search_client()\n client.search('cars', 'Toyota Corolla', {})\n\nContributing\n------------\n\nContributors are welcome!\n\n* Prior to opening a pull request, please create an issue to discuss the change/feature you've written/thinking of writing if it doesn't already exist.\n\n* Please write simple code and concise documentation, when appropriate.\n\n* Please write test cases to cover the code you've written, where possible.\n\n* Read the `Contributing <https://django-elastic-appsearch.readthedocs.io/en/latest/contributing.html#>`_ section of our documentation for more information around contributing to this project.\n\nRunning Tests\n-------------\n\nDoes the code actually work?\n\n::\n\n $ pipenv install --dev\n $ pipenv shell\n (django_elastic_appsearch) $ tox\n\nCredits\n-------\n\nTools used in rendering this package:\n\n* Cookiecutter_\n* `cookiecutter-djangopackage`_\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage\n\n\n\n\nHistory\n-------\n\n1.1.5 (2021-05-11)\n===================\n\n* Transfer ownership to Infoxchange\n* Update documentation\n* Dependency upgrades\n\n\n1.1.4 (2021-05-05)\n===================\n\n* Updated documentation\n* Dependency upgrades\n\n\n1.1.3 (2021-04-12)\n===================\n\n* Add Django 3.2 to the test matrix\n* Dependency upgrades\n* Minor fixes\n\n\n1.1.2 (2021-02-11)\n===================\n\n* Security patch\n\n\n1.1.1 (2021-02-04)\n===================\n\n* Dependency upgrades\n* Security patch\n* Improve returned responses\n\n\n1.1.0 (2021-01-27)\n===================\n\n* Dependecy upgrades\n* Add ability to index a model object into multiple app search engines\n\n\n1.0.2 (2020-12-29)\n===================\n\n* Dependency upgrades\n\n\n1.0.1 (2020-12-15)\n===================\n\n* Dependency upgrades\n\n\n1.0.0 (2020-11-26)\n===================\n\n* Python 3.9 support\n* Update the project status to stable\n\n\n0.7.6 (2020-11-26)\n===================\n\n* Dependency upgrades\n* Update documentation\n\n\n0.7.5 (2020-10-28)\n===================\n\n* Security patch\n\n\n0.7.4 (2020-10-05)\n===================\n\n* Add support for testing overridden queryset methods\n* Update documentation\n\n\n0.7.3 (2020-08-25)\n===================\n\n* Remove support for Django 2.0 and Django 2.1\n* Add support for Django 3.1\n* Update documentation\n\n\n0.7.2 (2020-08-25)\n===================\n\n* Dependency upgrades\n\n\n0.7.1 (2020-07-31)\n===================\n\n* Dependency upgrades\n\n\n0.7.0 (2020-07-30)\n===================\n\n* Implement ability to do partial updates to documents\n* Dependency upgrades\n\n\n0.6.11 (2020-06-22)\n===================\n\n* Fix failing dependency check with pipenv\n* Dependency upgrades\n\n\n0.6.9 (2020-05-15)\n==================\n\n* Dependency upgrades\n\n\n0.6.8 (2020-03-31)\n==================\n\n* Dependency upgrades\n* Security patches\n\n\n0.6.7 (2020-02-25)\n==================\n\n* Dependency upgrades\n\n\n0.6.6 (2020-02-01)\n==================\n\n* Dependency upgrades\n\n\n0.6.3 (2020-01-03)\n==================\n\n* Move from Travis CI to Github Actions\n* Documentation updates\n\n\n0.6.2 (2020-01-02)\n==================\n\n* Dependency upgrades\n* Documentation improvements\n* Add linting for CI\n* Setup automatic PyPI releases\n\n\n0.6.1 (2019-12-24)\n==================\n\n* Dependency upgrades\n\n\n0.6.0 (2019-12-04)\n==================\n\n* Remove support for Python 3.5\n* Add support for Python 3.8\n* Add support for Django 3\n* Dependency upgrades\n* Bump development status to Beta\n\n\n0.5.6 (2019-12-03)\n==================\n\n* Dependency upgrades\n\n\n0.5.5 (2019-11-14)\n==================\n\n* Dependency upgrades\n\n\n0.5.4 (2019-10-02)\n==================\n\n* Dependency upgrades\n\n\n0.5.3 (2019-08-28)\n==================\n\n* Improve documentation\n* Refactor settings name ``APPSEARCH_URL`` -> ``APPSEARCH_HOST``\n\n\n0.5.1 (2019-08-26)\n==================\n\n* Improve test coverage\n* Improve documentation\n* Add serpy as an official dependency\n* Bump dependency versions\n* Add code of conduct\n\n\n0.4.2 (2019-08-16)\n==================\n\n* Switch to the new official Elastic App Search python client\n* Documentation improvements\n\n\n0.2.3 (2019-08-02)\n==================\n\n* Use Pipenv for dependency management\n* Configure Dependabot for automatic dependency upgrades\n* Remove support for Python 3.4\n* Documentation improvements\n\n\n0.2.2 (2019-07-29)\n==================\n\n* Bug fixes\n* Documentation improvements\n\n\n0.1.0 (2019-07-26)\n==================\n\n* First release on PyPI.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Integrate your Django Project with Elastic App Search with ease.",
"version": "2.1.0",
"project_urls": {
"Homepage": "https://github.com/infoxchange/django_elastic_appsearch"
},
"split_keywords": [
"django_elastic_appsearch"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d6e43f0d8874dff32cde9c8c73583e721d15ef5e1e1e04ae9e20fed5046d80fc",
"md5": "d05a65e0f86dc19d0537be38919b8764",
"sha256": "c7be3891ea11b418437134794d244161c665e7c55b6072d05f9cecbf9497206c"
},
"downloads": -1,
"filename": "django_elastic_appsearch-2.1.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "d05a65e0f86dc19d0537be38919b8764",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 13495,
"upload_time": "2023-10-24T02:39:58",
"upload_time_iso_8601": "2023-10-24T02:39:58.979075Z",
"url": "https://files.pythonhosted.org/packages/d6/e4/3f0d8874dff32cde9c8c73583e721d15ef5e1e1e04ae9e20fed5046d80fc/django_elastic_appsearch-2.1.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e8ebd259e5f898e9fc239b15ceb3742883918f684933f5f6b5bd356d89558dcc",
"md5": "d3bb6d78cc1303fa7ed68cab352aee9a",
"sha256": "fc16e33c7c4a1e416ac236d6afd94cf758ea2a4e7dc3002f079420fa76a4cad3"
},
"downloads": -1,
"filename": "django_elastic_appsearch-2.1.0.tar.gz",
"has_sig": false,
"md5_digest": "d3bb6d78cc1303fa7ed68cab352aee9a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 18761,
"upload_time": "2023-10-24T02:40:01",
"upload_time_iso_8601": "2023-10-24T02:40:01.453792Z",
"url": "https://files.pythonhosted.org/packages/e8/eb/d259e5f898e9fc239b15ceb3742883918f684933f5f6b5bd356d89558dcc/django_elastic_appsearch-2.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-24 02:40:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "infoxchange",
"github_project": "django_elastic_appsearch",
"travis_ci": true,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "django-elastic-appsearch"
}