From 639758efc1245d3ae5d477f5ffddbaacaa002282 Mon Sep 17 00:00:00 2001
From: Luke Cousins <luke@breww.com>
Date: Tue, 22 Apr 2025 11:39:52 +0100
Subject: [PATCH 1/5] Switch to elasticsearch-py as dsl has been merged into it

---
 .github/workflows/ci.yml | 8 ++++----
 README.rst               | 4 ++--
 requirements.txt         | 2 +-
 requirements_dev.txt     | 2 +-
 setup.py                 | 2 +-
 tox.ini                  | 3 +--
 6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b384d05..1970dbe 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
       matrix:
         python-version: ["3.8", "3.9", "3.10", "3.11"]
         django-version: ["3.2", "4.1", "4.2"]
-        es-dsl-version: ["6.4", "7.4"]
+        es-py-version: ["9.0"]
         es-version: ["8.10.2"]
 
         exclude:
@@ -47,12 +47,12 @@ jobs:
         run: |
           python -m pip install --upgrade pip
           python -m pip install "Django==${{ matrix.django-version }}"
-          python -m pip install "elasticsearch-dsl==${{ matrix.es-dsl-version }}"
+          python -m pip install "elasticsearch==${{ matrix.es-py-version }}"
           python -m pip install -r requirements_test.txt
 
-      - name: Run tests with Python ${{ matrix.python-version }} and Django ${{ matrix.django-version }} and elasticsearch-dsl-py ${{ matrix.es-dsl-version }}
+      - name: Run tests with Python ${{ matrix.python-version }} and Django ${{ matrix.django-version }} and elasticsearch-py ${{ matrix.es-py-version }}
         run: |
-          TOX_ENV=$(echo "py${{ matrix.python-version }}-django-${{ matrix.django-version }}-es${{ matrix.es-dsl-version }}" | tr -d .)
+          TOX_ENV=$(echo "py${{ matrix.python-version }}-django-${{ matrix.django-version }}-es${{ matrix.es-py-version }}" | tr -d .)
           python -m tox -e $TOX_ENV -- --elasticsearch
           python -m tox -e $TOX_ENV -- --elasticsearch --signal-processor celery
 
diff --git a/README.rst b/README.rst
index eb29ad8..59d8b2b 100644
--- a/README.rst
+++ b/README.rst
@@ -12,8 +12,8 @@ Django Elasticsearch DSL
     :target: https://django-elasticsearch-dsl.readthedocs.io/en/latest/
 
 Django Elasticsearch DSL is a package that allows indexing of django models in elasticsearch.
-It is built as a thin wrapper around elasticsearch-dsl-py_
-so you can use all the features developed by the elasticsearch-dsl-py team.
+It is built as a thin wrapper around elasticsearch-py_
+so you can use all the features developed by the elasticsearch-py team.
 
 You can view the full documentation at https://django-elasticsearch-dsl.readthedocs.io
 
diff --git a/requirements.txt b/requirements.txt
index 53d79b3..4d7711e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
 django>=3.2
-elasticsearch-dsl>=8.0.0,<9.0.0
+elasticsearch>=9.0.0,<10.0.0
diff --git a/requirements_dev.txt b/requirements_dev.txt
index 43b5c3f..678ddba 100644
--- a/requirements_dev.txt
+++ b/requirements_dev.txt
@@ -1,7 +1,7 @@
 bumpversion==0.6.0
 wheel==0.41.2
 django>=3.2
-elasticsearch-dsl>=7.0.0,<8.0.0
+elasticsearch>=9.0.0,<10.0.0
 twine
 sphinx
 -e .
diff --git a/setup.py b/setup.py
index a3c60e1..bf15508 100755
--- a/setup.py
+++ b/setup.py
@@ -43,7 +43,7 @@
     ],
     include_package_data=True,
     install_requires=[
-        'elasticsearch-dsl>=8.9.0,<9.0.0',
+        'elasticsearch>=9.0.0,<10.0.0',
         'six',
     ],
     license="Apache Software License 2.0",
diff --git a/tox.ini b/tox.ini
index 54fd05f..f37de4a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,8 +13,7 @@ deps =
     django-32: Django>=3.2,<3.3
     django-41: Django>=4.1,<4.2
     django-42: Django>=4.2,<4.3
-    es64: elasticsearch-dsl>=6.4.0,<7.0.0
-    es74: elasticsearch-dsl>=7.4.0,<8
+    es9: elasticsearch>=9.0.0,<10
     -r{toxinidir}/requirements_test.txt
 
 basepython =

From a4cb97a88bc6a3d16796ab066365dc73d67e0450 Mon Sep 17 00:00:00 2001
From: Luke Cousins <luke@breww.com>
Date: Tue, 22 Apr 2025 11:45:40 +0100
Subject: [PATCH 2/5] Switch to elasticsearch-py as dsl has been merged into it

---
 django_elasticsearch_dsl/apps.py                       |  2 +-
 django_elasticsearch_dsl/documents.py                  |  4 ++--
 django_elasticsearch_dsl/fields.py                     |  2 +-
 django_elasticsearch_dsl/indices.py                    |  2 +-
 .../management/commands/search_index.py                |  2 +-
 django_elasticsearch_dsl/registries.py                 |  2 +-
 django_elasticsearch_dsl/search.py                     |  2 +-
 django_elasticsearch_dsl/test/testcases.py             |  2 +-
 docs/source/es_index.rst                               |  4 ++--
 example/test_app/documents.py                          |  2 +-
 tests/__init__.py                                      |  2 +-
 tests/documents.py                                     |  2 +-
 tests/test_documents.py                                | 10 +++++-----
 tests/test_integration.py                              |  2 +-
 14 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/django_elasticsearch_dsl/apps.py b/django_elasticsearch_dsl/apps.py
index 73e451c..884bedc 100644
--- a/django_elasticsearch_dsl/apps.py
+++ b/django_elasticsearch_dsl/apps.py
@@ -2,7 +2,7 @@
 from django.conf import settings
 from django.utils.module_loading import import_string
 
-from elasticsearch_dsl.connections import connections
+from elasticsearch.dsl.connections import connections
 
 
 class DEDConfig(AppConfig):
diff --git a/django_elasticsearch_dsl/documents.py b/django_elasticsearch_dsl/documents.py
index 4671064..b3d2145 100644
--- a/django_elasticsearch_dsl/documents.py
+++ b/django_elasticsearch_dsl/documents.py
@@ -7,7 +7,7 @@
 from django import VERSION as DJANGO_VERSION
 from django.db import models
 from elasticsearch.helpers import bulk, parallel_bulk
-from elasticsearch_dsl import Document as DSLDocument
+from elasticsearch.dsl import Document as DSLDocument
 from six import iteritems
 
 from .exceptions import ModelFieldNotMappedError
@@ -219,7 +219,7 @@ def _get_actions(self, object_list, action):
         for object_instance in object_list:
             if action == 'delete' or self.should_index_object(object_instance):
                 yield self._prepare_action(object_instance, action)
-    
+
     def get_actions(self, object_list, action):
         """
         Generate the elasticsearch payload.
diff --git a/django_elasticsearch_dsl/fields.py b/django_elasticsearch_dsl/fields.py
index 2652b68..1c63182 100644
--- a/django_elasticsearch_dsl/fields.py
+++ b/django_elasticsearch_dsl/fields.py
@@ -10,7 +10,7 @@
 else:
     from django.utils.encoding import force_str
 from django.utils.functional import Promise
-from elasticsearch_dsl.field import (
+from elasticsearch.dsl.field import (
     Boolean,
     Byte,
     Completion,
diff --git a/django_elasticsearch_dsl/indices.py b/django_elasticsearch_dsl/indices.py
index 115874d..b2a1ef7 100644
--- a/django_elasticsearch_dsl/indices.py
+++ b/django_elasticsearch_dsl/indices.py
@@ -1,6 +1,6 @@
 from copy import deepcopy
 
-from elasticsearch_dsl import Index as DSLIndex
+from elasticsearch.dsl import Index as DSLIndex
 from six import python_2_unicode_compatible
 
 from .apps import DEDConfig
diff --git a/django_elasticsearch_dsl/management/commands/search_index.py b/django_elasticsearch_dsl/management/commands/search_index.py
index 06bf851..4e31697 100644
--- a/django_elasticsearch_dsl/management/commands/search_index.py
+++ b/django_elasticsearch_dsl/management/commands/search_index.py
@@ -1,7 +1,7 @@
 from __future__ import unicode_literals, absolute_import
 from datetime import datetime
 
-from elasticsearch_dsl import connections
+from elasticsearch.dsl import connections
 from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError
 from six.moves import input
diff --git a/django_elasticsearch_dsl/registries.py b/django_elasticsearch_dsl/registries.py
index e2623dd..b7b1d51 100644
--- a/django_elasticsearch_dsl/registries.py
+++ b/django_elasticsearch_dsl/registries.py
@@ -5,7 +5,7 @@
 
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.exceptions import ImproperlyConfigured
-from elasticsearch_dsl import AttrDict
+from elasticsearch.dsl import AttrDict
 from six import itervalues, iterkeys, iteritems
 
 from django_elasticsearch_dsl.exceptions import RedeclaredFieldError
diff --git a/django_elasticsearch_dsl/search.py b/django_elasticsearch_dsl/search.py
index bc66d82..be0093a 100644
--- a/django_elasticsearch_dsl/search.py
+++ b/django_elasticsearch_dsl/search.py
@@ -1,7 +1,7 @@
 from django.db.models import Case, When
 from django.db.models.fields import IntegerField
 
-from elasticsearch_dsl import Search as DSLSearch
+from elasticsearch.dsl import Search as DSLSearch
 
 
 class Search(DSLSearch):
diff --git a/django_elasticsearch_dsl/test/testcases.py b/django_elasticsearch_dsl/test/testcases.py
index 12c3a80..43787b2 100644
--- a/django_elasticsearch_dsl/test/testcases.py
+++ b/django_elasticsearch_dsl/test/testcases.py
@@ -1,7 +1,7 @@
 import re
 
 from django.test.utils import captured_stderr
-from elasticsearch_dsl.connections import connections
+from elasticsearch.dsl.connections import connections
 
 from ..registries import registry
 
diff --git a/docs/source/es_index.rst b/docs/source/es_index.rst
index 618856d..963d3db 100644
--- a/docs/source/es_index.rst
+++ b/docs/source/es_index.rst
@@ -4,7 +4,7 @@ Index
 In typical scenario using `class Index` on a `Document` class is sufficient to perform any action.
 In a few cases though it can be useful to manipulate an Index object directly.
 
-To define an Elasticsearch index you must instantiate a ``elasticsearch_dsl.Index`` class
+To define an Elasticsearch index you must instantiate a ``elasticsearch.dsl.Index`` class
 and set the name and settings of the index.
 After you instantiate your class,
 you need to associate it with the Document you want to put in this Elasticsearch index
@@ -14,7 +14,7 @@ and also add the `registry.register_document` decorator.
 .. code-block:: python
 
     # documents.py
-    from elasticsearch_dsl import Index
+    from elasticsearch.dsl import Index
     from django_elasticsearch_dsl import Document
     from .models import Car, Manufacturer
 
diff --git a/example/test_app/documents.py b/example/test_app/documents.py
index e1e449d..693d665 100644
--- a/example/test_app/documents.py
+++ b/example/test_app/documents.py
@@ -1,4 +1,4 @@
-from elasticsearch_dsl import analyzer
+from elasticsearch.dsl import analyzer
 from django_elasticsearch_dsl import Document, Index, fields
 from django_elasticsearch_dsl.registries import registry
 
diff --git a/tests/__init__.py b/tests/__init__.py
index 7f06df2..296ec16 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,3 +1,3 @@
-from elasticsearch_dsl import VERSION
+from elasticsearch.dsl import VERSION
 
 ES_MAJOR_VERSION = VERSION[0]
diff --git a/tests/documents.py b/tests/documents.py
index 08ef83f..3074886 100644
--- a/tests/documents.py
+++ b/tests/documents.py
@@ -1,4 +1,4 @@
-from elasticsearch_dsl import analyzer
+from elasticsearch.dsl import analyzer
 from django_elasticsearch_dsl import Document, fields
 from django_elasticsearch_dsl.registries import registry
 
diff --git a/tests/test_documents.py b/tests/test_documents.py
index d7dd2ac..484dc0a 100644
--- a/tests/test_documents.py
+++ b/tests/test_documents.py
@@ -10,7 +10,7 @@
     from django.utils.translation import ugettext_lazy as _
 else:
     from django.utils.translation import gettext_lazy as _
-from elasticsearch_dsl import GeoPoint, InnerDoc
+from elasticsearch.dsl import GeoPoint, InnerDoc
 from mock import patch, Mock
 
 from django_elasticsearch_dsl import fields
@@ -453,7 +453,7 @@ def test_init_prepare_results(self):
     # got iterated and generate_id called.
     # If we mock the bulk in django_elasticsearch_dsl.document
     # the actual bulk will be never called and the test will fail
-    @patch('elasticsearch_dsl.connections.Elasticsearch.bulk')
+    @patch('elasticsearch.dsl.connections.Elasticsearch.bulk')
     def test_default_generate_id_is_called(self, _):
         article = Article(
             id=124594,
@@ -481,7 +481,7 @@ class Index:
             d.update(article)
             patched_method.assert_called()
 
-    @patch('elasticsearch_dsl.connections.Elasticsearch.bulk')
+    @patch('elasticsearch.dsl.connections.Elasticsearch.bulk')
     def test_custom_generate_id_is_called(self, mock_bulk):
         article = Article(
             id=54218,
@@ -511,7 +511,7 @@ def generate_id(cls, article):
         data = json.loads(mock_bulk.call_args[1]['operations'][1])
         assert data['slug'] == article.slug
 
-    @patch('elasticsearch_dsl.connections.Elasticsearch.bulk')
+    @patch('elasticsearch.dsl.connections.Elasticsearch.bulk')
     def test_should_index_object_is_called(self, mock_bulk):
         doc = CarDocument()
         car1 = Car()
@@ -525,7 +525,7 @@ def test_should_index_object_is_called(self, mock_bulk):
             self.assertEqual(mock_should_index_object.call_count, 3,
                              "should_index_object is called")
 
-    @patch('elasticsearch_dsl.connections.Elasticsearch.bulk')
+    @patch('elasticsearch.dsl.connections.Elasticsearch.bulk')
     def test_should_index_object_working_perfectly(self, mock_bulk):
         article1 = Article(slug='article1')
         article2 = Article(slug='article2')
diff --git a/tests/test_integration.py b/tests/test_integration.py
index f01d578..abb0b23 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -11,7 +11,7 @@
 from six import StringIO
 
 from elasticsearch.exceptions import NotFoundError
-from elasticsearch_dsl import Index as DSLIndex
+from elasticsearch.dsl import Index as DSLIndex
 from django_elasticsearch_dsl.test import ESTestCase, is_es_online
 from tests import ES_MAJOR_VERSION
 

From 8c68b9bb07956cdfd73c3eb8e260486b4eaa8117 Mon Sep 17 00:00:00 2001
From: Luke Cousins <luke@breww.com>
Date: Tue, 22 Apr 2025 12:09:56 +0100
Subject: [PATCH 3/5] Upgrade will need Elasticsearch v9

---
 README.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/README.rst b/README.rst
index 59d8b2b..a04bfb9 100644
--- a/README.rst
+++ b/README.rst
@@ -37,6 +37,8 @@ Features
 The library is compatible with all Elasticsearch versions since 5.x
 **but you have to use a matching major version:**
 
+- For Elasticsearch 9.0 and later, use the major version 9 (9.x.y) of the library.
+
 - For Elasticsearch 8.0 and later, use the major version 8 (8.x.y) of the library.
 
 - For Elasticsearch 7.0 and later, use the major version 7 (7.x.y) of the library.
@@ -45,6 +47,9 @@ The library is compatible with all Elasticsearch versions since 5.x
 
 .. code-block:: python
 
+    # Elasticsearch 9.x
+    elasticsearch-dsl>=9.0.0,<10.0.0
+
     # Elasticsearch 8.x
     elasticsearch-dsl>=8.0.0,<9.0.0
 

From 7b514692c40a215bac7908e4e348f6f2442fe38f Mon Sep 17 00:00:00 2001
From: Luke Cousins <luke@breww.com>
Date: Tue, 22 Apr 2025 12:27:19 +0100
Subject: [PATCH 4/5] Upgrade will need Elasticsearch v9

---
 setup.cfg | 2 +-
 setup.py  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/setup.cfg b/setup.cfg
index e3fc229..5674435 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 7.1.1
+current_version = 9.0
 commit = True
 tag = True
 
diff --git a/setup.py b/setup.py
index bf15508..46c3795 100755
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
 except ImportError:
     from distutils.core import setup
 
-version = '8.0'
+version = '9.0'
 
 if sys.argv[-1] == 'publish':
     try:

From 294f9364a22f789a066db9c7b0dbcfefa6d3fd7a Mon Sep 17 00:00:00 2001
From: Luke Cousins <luke@breww.com>
Date: Tue, 6 May 2025 16:06:40 +0100
Subject: [PATCH 5/5] Improve test running

---
 .github/workflows/ci.yml | 16 ++++++++++++----
 tox.ini                  | 11 +++++++++--
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1970dbe..8c74614 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,14 +13,22 @@ jobs:
       fail-fast: false
 
       matrix:
-        python-version: ["3.8", "3.9", "3.10", "3.11"]
-        django-version: ["3.2", "4.1", "4.2"]
-        es-py-version: ["9.0"]
-        es-version: ["8.10.2"]
+        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
+        django-version: ["3.2", "4.1", "4.2", "5.0", "5.1", "5.2"]
+        es-py-version: ["6.4", "7.4", "9.0"]
+        es-version: ["8.10.2", "9.0.0"]
 
         exclude:
           - python-version: "3.11"
             django-version: "3.2"
+          - python-version: "3.12"
+            django-version: "3.2"
+          - python-version: "3.13"
+            django-version: "3.2"
+          - es-py-version: "6.4"
+            es-version: "8.10.2"
+          - es-py-version: "7.4"
+            es-version: "8.10.2"
 
     steps:
       - name: Install and Run Elasticsearch
diff --git a/tox.ini b/tox.ini
index f37de4a..e63c200 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
 [tox]
 envlist =
-    py{38,39,310}-django-{32,41,42}-{es64,es74}
-    py{311}-django-{41,42}-{es64,es74}
+    py{38,39,310,311}-django-{32,41,42}-{es64,es74,es9}
+    py{311,312,313}-django-{41,42,50,5152}-{es64,es74,es9}
 
 
 [testenv]
@@ -13,6 +13,11 @@ deps =
     django-32: Django>=3.2,<3.3
     django-41: Django>=4.1,<4.2
     django-42: Django>=4.2,<4.3
+    django-50: Django>=5.0,<5.1
+    django-51: Django>=5.1,<5.2
+    django-52: Django>=5.2,<5.3
+    es64: elasticsearch-dsl>=6.4.0,<7.0.0
+    es74: elasticsearch-dsl>=7.4.0,<8
     es9: elasticsearch>=9.0.0,<10
     -r{toxinidir}/requirements_test.txt
 
@@ -21,3 +26,5 @@ basepython =
     py39: python3.9
     py310: python3.10
     py311: python3.11
+    py312: python3.12
+    py313: python3.13