django-cte 1.3.2__tar.gz → 1.3.3.dev20250526204410__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,84 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-cte
3
+ Version: 1.3.3.dev20250526204410
4
+ Summary: Common Table Expressions (CTE) for Django
5
+ Author-email: Daniel Miller <millerdev@gmail.com>
6
+ Requires-Python: >= 3.9
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Django
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Framework :: Django
22
+ Classifier: Framework :: Django :: 4
23
+ Classifier: Framework :: Django :: 4.2
24
+ Classifier: Framework :: Django :: 5
25
+ Classifier: Framework :: Django :: 5.0
26
+ Classifier: Framework :: Django :: 5.1
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ License-File: LICENSE
29
+ Requires-Dist: django
30
+ Project-URL: Home, https://github.com/dimagi/django-cte
31
+
32
+ # Common Table Expressions with Django
33
+
34
+ [![Build Status](https://github.com/dimagi/django-cte/actions/workflows/tests.yml/badge.svg)](https://github.com/dimagi/django-cte/actions/workflows/tests.yml)
35
+ [![PyPI version](https://badge.fury.io/py/django-cte.svg)](https://badge.fury.io/py/django-cte)
36
+
37
+ ## Installation
38
+ ```
39
+ pip install django-cte
40
+ ```
41
+
42
+
43
+ ## Documentation
44
+
45
+ The [django-cte documentation](https://dimagi.github.io/django-cte/) shows how
46
+ to use Common Table Expressions with the Django ORM.
47
+
48
+
49
+ ## Running tests
50
+
51
+ ```
52
+ cd django-cte
53
+ uv sync
54
+
55
+ pytest
56
+ ruff check
57
+
58
+ # To run tests against postgres
59
+ psql -U username -h localhost -p 5432 -c 'create database django_cte;'
60
+ export PG_DB_SETTINGS='{
61
+ "ENGINE":"django.db.backends.postgresql_psycopg2",
62
+ "NAME":"django_cte",
63
+ "USER":"username",
64
+ "PASSWORD":"password",
65
+ "HOST":"localhost",
66
+ "PORT":"5432"}'
67
+
68
+ # WARNING pytest will delete the test_django_cte database if it exists!
69
+ DB_SETTINGS="$PG_DB_SETTINGS" pytest
70
+ ```
71
+
72
+ All feature and bug contributions are expected to be covered by tests.
73
+
74
+
75
+ ## Publishing a new verison to PyPI
76
+
77
+ Push a new tag to Github using the format vX.Y.Z where X.Y.Z matches the version
78
+ in [`__init__.py`](django_cte/__init__.py).
79
+
80
+ A new version is published to https://test.pypi.org/p/django-cte on every
81
+ push to the *main* branch.
82
+
83
+ Publishing is automated with [Github Actions](.github/workflows/pypi.yml).
84
+
@@ -0,0 +1,52 @@
1
+ # Common Table Expressions with Django
2
+
3
+ [![Build Status](https://github.com/dimagi/django-cte/actions/workflows/tests.yml/badge.svg)](https://github.com/dimagi/django-cte/actions/workflows/tests.yml)
4
+ [![PyPI version](https://badge.fury.io/py/django-cte.svg)](https://badge.fury.io/py/django-cte)
5
+
6
+ ## Installation
7
+ ```
8
+ pip install django-cte
9
+ ```
10
+
11
+
12
+ ## Documentation
13
+
14
+ The [django-cte documentation](https://dimagi.github.io/django-cte/) shows how
15
+ to use Common Table Expressions with the Django ORM.
16
+
17
+
18
+ ## Running tests
19
+
20
+ ```
21
+ cd django-cte
22
+ uv sync
23
+
24
+ pytest
25
+ ruff check
26
+
27
+ # To run tests against postgres
28
+ psql -U username -h localhost -p 5432 -c 'create database django_cte;'
29
+ export PG_DB_SETTINGS='{
30
+ "ENGINE":"django.db.backends.postgresql_psycopg2",
31
+ "NAME":"django_cte",
32
+ "USER":"username",
33
+ "PASSWORD":"password",
34
+ "HOST":"localhost",
35
+ "PORT":"5432"}'
36
+
37
+ # WARNING pytest will delete the test_django_cte database if it exists!
38
+ DB_SETTINGS="$PG_DB_SETTINGS" pytest
39
+ ```
40
+
41
+ All feature and bug contributions are expected to be covered by tests.
42
+
43
+
44
+ ## Publishing a new verison to PyPI
45
+
46
+ Push a new tag to Github using the format vX.Y.Z where X.Y.Z matches the version
47
+ in [`__init__.py`](django_cte/__init__.py).
48
+
49
+ A new version is published to https://test.pypi.org/p/django-cte on every
50
+ push to the *main* branch.
51
+
52
+ Publishing is automated with [Github Actions](.github/workflows/pypi.yml).
@@ -0,0 +1,3 @@
1
+ from .cte import CTEManager, CTEQuerySet, With # noqa
2
+
3
+ __version__ = "1.3.3.dev20250526204410"
@@ -1,6 +1,3 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
1
  from django.db.models import Manager
5
2
  from django.db.models.query import Q, QuerySet, ValuesIterable
6
3
  from django.db.models.sql.datastructures import BaseTable
@@ -109,6 +106,7 @@ class With(object):
109
106
  query = CTEQuery(cte_query.model)
110
107
  query.join(BaseTable(self.name, None))
111
108
  query.default_cols = cte_query.default_cols
109
+ query.deferred_loading = cte_query.deferred_loading
112
110
  if cte_query.annotations:
113
111
  for alias, value in cte_query.annotations.items():
114
112
  col = CTEColumnRef(alias, self.name, value.output_field)
@@ -1,5 +1,3 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
1
  from django.db.models.sql.constants import INNER
4
2
 
5
3
 
@@ -1,6 +1,3 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
1
  import weakref
5
2
 
6
3
  from django.db.models.expressions import Col, Expression
@@ -1,7 +1,5 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
1
  import django
2
+ from django.core.exceptions import EmptyResultSet
5
3
  from django.db import connections
6
4
  from django.db.models.sql import DeleteQuery, Query, UpdateQuery
7
5
  from django.db.models.sql.compiler import (
@@ -9,8 +7,11 @@ from django.db.models.sql.compiler import (
9
7
  SQLDeleteCompiler,
10
8
  SQLUpdateCompiler,
11
9
  )
10
+ from django.db.models.sql.constants import LOUTER
11
+ from django.db.models.sql.where import ExtraWhere, WhereNode
12
12
 
13
13
  from .expressions import CTESubqueryResolver
14
+ from .join import QJoin
14
15
 
15
16
 
16
17
  class CTEQuery(Query):
@@ -67,7 +68,7 @@ class CTECompiler(object):
67
68
 
68
69
  @classmethod
69
70
  def generate_sql(cls, connection, query, as_sql):
70
- if query.combinator:
71
+ if not query._with_ctes:
71
72
  return as_sql()
72
73
 
73
74
  ctes = []
@@ -75,28 +76,69 @@ class CTECompiler(object):
75
76
  for cte in query._with_ctes:
76
77
  if django.VERSION > (4, 2):
77
78
  _ignore_with_col_aliases(cte.query)
78
- compiler = cte.query.get_compiler(connection=connection)
79
+
80
+ alias = query.alias_map.get(cte.name)
81
+ should_elide_empty = (
82
+ not isinstance(alias, QJoin) or alias.join_type != LOUTER
83
+ )
84
+
85
+ if django.VERSION >= (4, 0):
86
+ compiler = cte.query.get_compiler(
87
+ connection=connection, elide_empty=should_elide_empty
88
+ )
89
+ else:
90
+ compiler = cte.query.get_compiler(connection=connection)
91
+
79
92
  qn = compiler.quote_name_unless_alias
80
- cte_sql, cte_params = compiler.as_sql()
93
+ try:
94
+ cte_sql, cte_params = compiler.as_sql()
95
+ except EmptyResultSet:
96
+ if django.VERSION < (4, 0) and not should_elide_empty:
97
+ # elide_empty is not available prior to Django 4.0. The
98
+ # below behavior emulates the logic of it, rebuilding
99
+ # the CTE query with a WHERE clause that is always false
100
+ # but that the SqlCompiler cannot optimize away. This is
101
+ # only required for left outer joins, as standard inner
102
+ # joins should be optimized and raise the EmptyResultSet
103
+ query = cte.query.copy()
104
+ query.where = WhereNode([ExtraWhere(["1 = 0"], [])])
105
+ compiler = query.get_compiler(connection=connection)
106
+ cte_sql, cte_params = compiler.as_sql()
107
+ else:
108
+ # If the CTE raises an EmptyResultSet the SqlCompiler still
109
+ # needs to know the information about this base compiler
110
+ # like, col_count and klass_info.
111
+ as_sql()
112
+ raise
81
113
  template = cls.get_cte_query_template(cte)
82
114
  ctes.append(template.format(name=qn(cte.name), query=cte_sql))
83
115
  params.extend(cte_params)
84
116
 
85
- explain_query = getattr(query, "explain_query", None)
86
- sql = []
87
- if explain_query:
117
+ # Required due to breaking change in django commit
118
+ # fc91ea1e50e5ef207f0f291b3f6c1942b10db7c7
119
+ if django.VERSION >= (4, 0):
120
+ explain_attribute = "explain_info"
121
+ explain_info = getattr(query, explain_attribute, None)
122
+ explain_format = getattr(explain_info, "format", None)
123
+ explain_options = getattr(explain_info, "options", {})
124
+ else:
125
+ explain_attribute = "explain_query"
88
126
  explain_format = getattr(query, "explain_format", None)
89
127
  explain_options = getattr(query, "explain_options", {})
128
+
129
+ explain_query_or_info = getattr(query, explain_attribute, None)
130
+ sql = []
131
+ if explain_query_or_info:
90
132
  sql.append(
91
133
  connection.ops.explain_query_prefix(
92
134
  explain_format,
93
135
  **explain_options
94
136
  )
95
137
  )
96
- # this needs to get set to False so that the base as_sql() doesn't
138
+ # this needs to get set to None so that the base as_sql() doesn't
97
139
  # insert the EXPLAIN statement where it would end up between the
98
140
  # WITH ... clause and the final SELECT
99
- query.explain_query = False
141
+ setattr(query, explain_attribute, None)
100
142
 
101
143
  if ctes:
102
144
  # Always use WITH RECURSIVE
@@ -104,8 +146,8 @@ class CTECompiler(object):
104
146
  sql.extend(["WITH RECURSIVE", ", ".join(ctes)])
105
147
  base_sql, base_params = as_sql()
106
148
 
107
- if explain_query:
108
- query.explain_query = explain_query
149
+ if explain_query_or_info:
150
+ setattr(query, explain_attribute, explain_query_or_info)
109
151
 
110
152
  sql.append(base_sql)
111
153
  params.extend(base_params)
@@ -1,7 +1,3 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
-
5
1
  def raw_cte_sql(sql, params, refs):
6
2
  """Raw CTE SQL
7
3
 
@@ -32,7 +28,7 @@ def raw_cte_sql(sql, params, refs):
32
28
  class raw_cte_queryset(object):
33
29
  class query(object):
34
30
  @staticmethod
35
- def get_compiler(connection):
31
+ def get_compiler(connection, *, elide_empty=None):
36
32
  return raw_cte_compiler(connection)
37
33
 
38
34
  @staticmethod
@@ -0,0 +1,51 @@
1
+ [project]
2
+ name = "django-cte"
3
+ description = "Common Table Expressions (CTE) for Django"
4
+ authors = [{name = "Daniel Miller", email = "millerdev@gmail.com"}]
5
+ license = {file = "LICENSE"}
6
+ readme = {file = "README.md", content-type = "text/markdown"}
7
+ dynamic = ["version"]
8
+ requires-python = ">= 3.9"
9
+ classifiers = [
10
+ "Development Status :: 5 - Production/Stable",
11
+ 'Environment :: Web Environment',
12
+ 'Framework :: Django',
13
+ 'Intended Audience :: Developers',
14
+ 'License :: OSI Approved :: BSD License',
15
+ 'Operating System :: OS Independent',
16
+ 'Programming Language :: Python',
17
+ 'Programming Language :: Python :: 3',
18
+ 'Programming Language :: Python :: 3.9',
19
+ 'Programming Language :: Python :: 3.10',
20
+ 'Programming Language :: Python :: 3.11',
21
+ 'Programming Language :: Python :: 3.12',
22
+ 'Programming Language :: Python :: 3.13',
23
+ 'Framework :: Django',
24
+ 'Framework :: Django :: 4',
25
+ 'Framework :: Django :: 4.2',
26
+ 'Framework :: Django :: 5',
27
+ 'Framework :: Django :: 5.0',
28
+ 'Framework :: Django :: 5.1',
29
+ 'Topic :: Software Development :: Libraries :: Python Modules',
30
+ ]
31
+ dependencies = ["django"]
32
+
33
+ [dependency-groups]
34
+ dev = [
35
+ "psycopg2-binary",
36
+ "pytest-unmagic",
37
+ "ruff",
38
+ ]
39
+
40
+ [project.urls]
41
+ Home = "https://github.com/dimagi/django-cte"
42
+
43
+ [build-system]
44
+ requires = ["flit_core >=3.2,<4"]
45
+ build-backend = "flit_core.buildapi"
46
+
47
+ [tool.flit.module]
48
+ name = "django_cte"
49
+
50
+ [tool.distutils.bdist_wheel]
51
+ universal = true
django-cte-1.3.2/PKG-INFO DELETED
@@ -1,81 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: django-cte
3
- Version: 1.3.2
4
- Summary: Common Table Expressions (CTE) for Django
5
- Home-page: https://github.com/dimagi/django-cte
6
- Maintainer: Daniel Miller
7
- Maintainer-email: millerdev@gmail.com
8
- License: BSD License
9
- Platform: UNKNOWN
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Environment :: Web Environment
12
- Classifier: Framework :: Django
13
- Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: BSD License
15
- Classifier: Operating System :: OS Independent
16
- Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.6
19
- Classifier: Programming Language :: Python :: 3.7
20
- Classifier: Programming Language :: Python :: 3.8
21
- Classifier: Programming Language :: Python :: 3.9
22
- Classifier: Programming Language :: Python :: 3.10
23
- Classifier: Programming Language :: Python :: 3.11
24
- Classifier: Programming Language :: Python :: 3.12
25
- Classifier: Framework :: Django
26
- Classifier: Framework :: Django :: 2
27
- Classifier: Framework :: Django :: 2.2
28
- Classifier: Framework :: Django :: 3
29
- Classifier: Framework :: Django :: 3.0
30
- Classifier: Framework :: Django :: 3.1
31
- Classifier: Framework :: Django :: 3.2
32
- Classifier: Framework :: Django :: 4
33
- Classifier: Framework :: Django :: 4.0
34
- Classifier: Framework :: Django :: 4.2
35
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
36
- Description-Content-Type: text/markdown
37
- License-File: LICENSE
38
-
39
- # Common Table Expressions with Django
40
-
41
- [![Build Status](https://travis-ci.com/dimagi/django-cte.png)](https://travis-ci.com/dimagi/django-cte)
42
- [![PyPI version](https://badge.fury.io/py/django-cte.svg)](https://badge.fury.io/py/django-cte)
43
-
44
- ## Installation
45
- ```
46
- pip install django-cte
47
- ```
48
-
49
-
50
- ## Documentation
51
-
52
- The [django-cte documentation](https://dimagi.github.io/django-cte/) shows how
53
- to use Common Table Expressions with the Django ORM.
54
-
55
-
56
- ## Running tests
57
-
58
- ```
59
- cd django-cte
60
- mkvirtualenv cte # or however you choose to setup your environment
61
- pip install django pynose flake8
62
-
63
- nosetests
64
- flake8 --config=setup.cfg
65
- ```
66
-
67
- All feature and bug contributions are expected to be covered by tests.
68
-
69
-
70
- ## Uploading to PyPI
71
-
72
- Package and upload the generated files.
73
-
74
- ```
75
- pip install -r pkg-requires.txt
76
-
77
- python setup.py sdist bdist_wheel
78
- twine upload dist/*
79
- ```
80
-
81
-
@@ -1,41 +0,0 @@
1
- # Common Table Expressions with Django
2
-
3
- [![Build Status](https://travis-ci.com/dimagi/django-cte.png)](https://travis-ci.com/dimagi/django-cte)
4
- [![PyPI version](https://badge.fury.io/py/django-cte.svg)](https://badge.fury.io/py/django-cte)
5
-
6
- ## Installation
7
- ```
8
- pip install django-cte
9
- ```
10
-
11
-
12
- ## Documentation
13
-
14
- The [django-cte documentation](https://dimagi.github.io/django-cte/) shows how
15
- to use Common Table Expressions with the Django ORM.
16
-
17
-
18
- ## Running tests
19
-
20
- ```
21
- cd django-cte
22
- mkvirtualenv cte # or however you choose to setup your environment
23
- pip install django pynose flake8
24
-
25
- nosetests
26
- flake8 --config=setup.cfg
27
- ```
28
-
29
- All feature and bug contributions are expected to be covered by tests.
30
-
31
-
32
- ## Uploading to PyPI
33
-
34
- Package and upload the generated files.
35
-
36
- ```
37
- pip install -r pkg-requires.txt
38
-
39
- python setup.py sdist bdist_wheel
40
- twine upload dist/*
41
- ```
@@ -1,6 +0,0 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
- from .cte import CTEManager, CTEQuerySet, With # noqa
5
-
6
- __version__ = "1.3.2"
@@ -1,81 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: django-cte
3
- Version: 1.3.2
4
- Summary: Common Table Expressions (CTE) for Django
5
- Home-page: https://github.com/dimagi/django-cte
6
- Maintainer: Daniel Miller
7
- Maintainer-email: millerdev@gmail.com
8
- License: BSD License
9
- Platform: UNKNOWN
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Environment :: Web Environment
12
- Classifier: Framework :: Django
13
- Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: BSD License
15
- Classifier: Operating System :: OS Independent
16
- Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.6
19
- Classifier: Programming Language :: Python :: 3.7
20
- Classifier: Programming Language :: Python :: 3.8
21
- Classifier: Programming Language :: Python :: 3.9
22
- Classifier: Programming Language :: Python :: 3.10
23
- Classifier: Programming Language :: Python :: 3.11
24
- Classifier: Programming Language :: Python :: 3.12
25
- Classifier: Framework :: Django
26
- Classifier: Framework :: Django :: 2
27
- Classifier: Framework :: Django :: 2.2
28
- Classifier: Framework :: Django :: 3
29
- Classifier: Framework :: Django :: 3.0
30
- Classifier: Framework :: Django :: 3.1
31
- Classifier: Framework :: Django :: 3.2
32
- Classifier: Framework :: Django :: 4
33
- Classifier: Framework :: Django :: 4.0
34
- Classifier: Framework :: Django :: 4.2
35
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
36
- Description-Content-Type: text/markdown
37
- License-File: LICENSE
38
-
39
- # Common Table Expressions with Django
40
-
41
- [![Build Status](https://travis-ci.com/dimagi/django-cte.png)](https://travis-ci.com/dimagi/django-cte)
42
- [![PyPI version](https://badge.fury.io/py/django-cte.svg)](https://badge.fury.io/py/django-cte)
43
-
44
- ## Installation
45
- ```
46
- pip install django-cte
47
- ```
48
-
49
-
50
- ## Documentation
51
-
52
- The [django-cte documentation](https://dimagi.github.io/django-cte/) shows how
53
- to use Common Table Expressions with the Django ORM.
54
-
55
-
56
- ## Running tests
57
-
58
- ```
59
- cd django-cte
60
- mkvirtualenv cte # or however you choose to setup your environment
61
- pip install django pynose flake8
62
-
63
- nosetests
64
- flake8 --config=setup.cfg
65
- ```
66
-
67
- All feature and bug contributions are expected to be covered by tests.
68
-
69
-
70
- ## Uploading to PyPI
71
-
72
- Package and upload the generated files.
73
-
74
- ```
75
- pip install -r pkg-requires.txt
76
-
77
- python setup.py sdist bdist_wheel
78
- twine upload dist/*
79
- ```
80
-
81
-
@@ -1,15 +0,0 @@
1
- LICENSE
2
- README.md
3
- setup.cfg
4
- setup.py
5
- django_cte/__init__.py
6
- django_cte/cte.py
7
- django_cte/expressions.py
8
- django_cte/join.py
9
- django_cte/meta.py
10
- django_cte/query.py
11
- django_cte/raw.py
12
- django_cte.egg-info/PKG-INFO
13
- django_cte.egg-info/SOURCES.txt
14
- django_cte.egg-info/dependency_links.txt
15
- django_cte.egg-info/top_level.txt
@@ -1 +0,0 @@
1
- django_cte
@@ -1,13 +0,0 @@
1
- [bdist_wheel]
2
- universal = 1
3
-
4
- [metadata]
5
- license_file = LICENSE
6
-
7
- [flake8]
8
- exclude = ./build
9
-
10
- [egg_info]
11
- tag_build =
12
- tag_date = 0
13
-
django-cte-1.3.2/setup.py DELETED
@@ -1,64 +0,0 @@
1
- from __future__ import absolute_import
2
- from __future__ import unicode_literals
3
-
4
- import os
5
- import re
6
- from io import open
7
-
8
- from setuptools import find_packages, setup
9
-
10
-
11
- def get_version(filename):
12
- path = os.path.join(os.path.dirname(__file__), filename)
13
- with open(path, encoding="utf-8") as handle:
14
- content = handle.read()
15
- return re.search(r'__version__ = "([^"]+)"', content).group(1)
16
-
17
-
18
- def read_md(filename):
19
- path = os.path.join(os.path.dirname(__file__), filename)
20
- with open(path, encoding='utf-8') as handle:
21
- return handle.read()
22
-
23
-
24
- setup(
25
- name='django-cte',
26
- version=get_version('django_cte/__init__.py'),
27
- description='Common Table Expressions (CTE) for Django',
28
- long_description=read_md('README.md'),
29
- long_description_content_type='text/markdown',
30
- maintainer='Daniel Miller',
31
- maintainer_email='millerdev@gmail.com',
32
- url='https://github.com/dimagi/django-cte',
33
- license='BSD License',
34
- packages=find_packages(exclude=['tests']),
35
- include_package_data=True,
36
- classifiers=[
37
- 'Development Status :: 3 - Alpha',
38
- 'Environment :: Web Environment',
39
- 'Framework :: Django',
40
- 'Intended Audience :: Developers',
41
- 'License :: OSI Approved :: BSD License',
42
- 'Operating System :: OS Independent',
43
- 'Programming Language :: Python',
44
- 'Programming Language :: Python :: 3',
45
- 'Programming Language :: Python :: 3.6',
46
- 'Programming Language :: Python :: 3.7',
47
- 'Programming Language :: Python :: 3.8',
48
- 'Programming Language :: Python :: 3.9',
49
- 'Programming Language :: Python :: 3.10',
50
- 'Programming Language :: Python :: 3.11',
51
- 'Programming Language :: Python :: 3.12',
52
- 'Framework :: Django',
53
- 'Framework :: Django :: 2',
54
- 'Framework :: Django :: 2.2',
55
- 'Framework :: Django :: 3',
56
- 'Framework :: Django :: 3.0',
57
- 'Framework :: Django :: 3.1',
58
- 'Framework :: Django :: 3.2',
59
- 'Framework :: Django :: 4',
60
- 'Framework :: Django :: 4.0',
61
- 'Framework :: Django :: 4.2',
62
- 'Topic :: Software Development :: Libraries :: Python Modules',
63
- ],
64
- )