- BREAKING: on Django 5.2 and later when joining a CTE to a queryset with
LEFT OUTER JOIN (
_join_type=LOUTER) and the join condition implicitly joins a related table, the implicit join is now a LEFT OUTER JOIN instead of an INNER JOIN. This makes the join behavior match SQL database semantics: the left-side rows are always preserved. To restore the old behavior, either do not use_join_type=LOUTERor add extra WHERE conditions as needed. See #130 for more details. - Fixed
CTE.queryset()queries involving aggregates (#128). - Fixed Django 5.2 ambiguous column names bug (#127).
- Fixed possible ambiguous column names in SQL (#125).
- Fixed Django 5.2
CTE.queryset()regression (#124).
- API overhaul
Withhas been renamed toCTE.Withis deprecated and will be removed in a future version of django-cte.with_ctewas moved from aCTEQuerySetmethod to a stand-alone function.CTEManagerandCTEQuerySetare deprecated and should be removed from code that uses them, as they are no longer necessary. They will be removed in a future version of django-cte.- Reference the documentation for new usage patterns.
- BREAKING: On Django 5.2 and later, the name specified in
.values('fk_name')must match the name of the same column referenced bycte.col.fk_name—for example, in a join condition. It may end with_idor not, but the references must be consistent. This change may require previously working CTE queries to be adjusted when migrating to Django 5.2 (example). - Django 5.0 is EOL and no longer supported.
- Fixed broken
UNIONand other "combined" queries. - Internally, the library has been updated to simplify the code and remove workarounds for old and unsupported versions of Django.
- Modernized development tooling
- Replaced nosetests with pytest.
- Replaced setup.py with pyproject.toml
- Replaced flake8 with ruff.
- Replaced venv/pip with uv.
- Improved Github Actions automation, including automated releases.
- Dev versions of django-cte are now published on PyPI, making them easier to test and use before an official release is cut.
- Handle empty result sets in CTEs (#92).
- Fix
.explain()in Django >= 4.0 (#91). - Fixed bug in deferred loading (#90).
- Work around changes in Django 4.2 that broke CTE queries due to internally generated column aliases in the query compiler. The workaround is not always effective. Some queries will produce mal-formed SQL. For example, CTE queries with window functions.
- Fix:
.update()did not work when using CTE manager or when accessing nested tables.
- Add support for Materialized CTEs.
- Fix: add EXPLAIN clause in correct position when using
.explain()method.
- Fix compatibility with non-CTE models.
- Add support for Django 3.1, 3.2 and 4.0.
- Quote the CTE table name if needed.
- Resolve
OuterRefin CTESubquery. - Fix default
CTEManagerso it can usefrom_querysetcorectly. - Fix for Django 3.0.5+.
- Django 3 compatibility. Thank you @tim-schilling and @ryanhiebert!
- Python 3 compatibility.
- Fix CTE alias bug.
- Use
_default_managerinstead ofobjects.
- Fix recursive CTE pickling. Note: this is currently broken on Django master.
With.queryset()now uses the CTE model's manager to create a newQuerySet, which makes it easier to work with customQuerySetclasses.
- BACKWARD INCOMPATIBLE CHANGE:
With.queryset()no longer accepts amodelargument. - Improve
With.queryset()to select directly from the CTE rather than joining to anoter QuerySet. - Refactor
With.join()to use real JOIN clause.
- Fix related field attname masking CTE column.
- Add
django_cte.raw.raw_cte_sqlfor constructing CTEs with raw SQL.
- Improve error on bad recursive reference.
- Add more tests.
- Add change log.
- Improve README.
- PEP-8 style fixes.
- Fix readme formatting on PyPI.
- Initial implementation.