Skip to content

Bump django-tables2 from 2.7.0 to 3.0.0 - #38072

Open
dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/uv/django-tables2-3.0.0
Open

Bump django-tables2 from 2.7.0 to 3.0.0#38072
dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/uv/django-tables2-3.0.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 27, 2026

Copy link
Copy Markdown
Contributor

Bumps django-tables2 from 2.7.0 to 3.0.0.

Changelog

Sourced from django-tables2's changelog.

3.0.0 (2026-04-13)

Breaking changes:

  • Rename the querystring templatetag to querystring_replace to avoid shadowing built-in one. If you use custom templates to render tables with django-tables2, you should replace {% querystring %} with {% querystring_replace %}
  • RelatedLinkColumn is removed. Replace RelatedLinkColumn with Column(linkify=True).

Changes:

  • Restore signature of TemplateColumn.render() (#1033) by @​gythaogg fixes #1032
  • Remove declared support for Django 4.2 and 5.1, upgrade pre-commit dependencies (#1030)

2.9.0 (2026-04-06)

This release is yanked because it should have been released as 3.0 because of the breaking changes.

Changes:

  • Remove deprecated RelatedLinkColumn and NullBooleanField support (#1016) NullBooleanField was removed in django 4.0
  • Export DateColumn/DateTimeColumn/TimeColumn in ISO format (#1022 by @​spapas)
  • Rename querystring template tag to querystring_replace (#1021 by @​federicobond)
  • Use string annotation_format in inspect.signature to prevent runtime errors with type annotations (#1027) by @​mschoettle
  • Add optional context_object_name to TemplateColumn and make extra_context optionally callable (#931) fixes: #928

2.8.0 (2025-11-21)

  • Pass request to the template rendered in TemplateColumn (#1014) Fixes: #1008
  • Do not generate error when table data model is subclass of table model (#1015) Fixes #1010 by @​sjoerdjob
  • Update supported Python and Django versions (#1011) by @​dyve Supported Django versions: 4.2, 5.1, 5.2, 6.0 Supported Python versions: 3.10, 3.11, 3.12, 3.13, 3.14

2.7.5 (2025-01-02)

2.7.4 & 2.7.3 (2024-12-23)

Correct packaging mistakes:

  • Remove upper bound for python_requires

2.7.2 (2024-12-23)

  • Add python_requires to setup.py (#982) Fixes: #980

2.7.1 (2024-12-21)

  • Add TimeColumn to built-in columns (#937) by @​philipphanemann Add support to pass args/kwargs to callables from Accessor (#940), fixes: #939 by @​JordanHyatt
  • Drop support for Django 3.2, 4.1 and python 3.8
  • Add support for Django 5.1 and python 3.12
  • Explicitly set Column.accessor when binding a column to allow column methods like order_by to use its value (#979)
Commits
  • bae55f2 Prepare release 3.0.0
  • a2869f3 Remove declared support for Django 4.2 and 5.1, upgrade pre-commit dependenci...
  • 171d890 Restore signature of TemplateColumn.render() (#1033)
  • ba66a7f Prepare releasing version 2.9.0
  • aa62684 Document merging #1027, #931
  • 85f1050 Add optional context_object_name to TemplateColumn and make `extra_contex...
  • 99fa419 Use string annotation_format in inspect.signature to prevent runtime errors w...
  • 82451a9 Bump actions/cache from 5.0.1 to 5.0.4 (#1028)
  • b1c08a3 Update changelog after merging #1016, #1022, #1021
  • c4aff9b Rename querystring templatetag to querystring_replace (#1021)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [django-tables2](https://github.com/jieter/django-tables2) from 2.7.0 to 3.0.0.
- [Changelog](https://github.com/jieter/django-tables2/blob/master/CHANGELOG.md)
- [Commits](jieter/django-tables2@v2.7.0...v3.0.0)

---
updated-dependencies:
- dependency-name: django-tables2
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added the product/invisible Change has no end-user visible impact label Aug 27, 2026
@dependabot
dependabot Bot requested a review from a team as a code owner August 27, 2026 10:05
@dependabot dependabot Bot added the product/invisible Change has no end-user visible impact label Aug 27, 2026
@dimagimon dimagimon added the dependencies Pull requests that update a dependency file label Aug 27, 2026
@claude

claude Bot commented Aug 27, 2026

Copy link
Copy Markdown

🔍 Dependency Analysis Summary

This bump crosses a major boundary that renames the {% querystring %} template tag to {% querystring_replace %}. CommCare HQ calls that tag in 39 places across 19 templates, including the shared table scaffolding in hqwebapp/templates/hqwebapp/tables/, so this is not a drop-in lock bump. As-is it breaks table rendering for Data Cleaning, KYC, Payments, and the Styleguide.

Overall risk: HIGH


📋 Detailed Changelog Review

django-tables2 (2.7.0 → 3.0.0)

2.9.0 was yanked upstream and re-cut as 3.0.0, so this really spans 2.7.1 → 3.0.0.

Changes

  • querystring template tag renamed to querystring_replace, to stop shadowing Django's built-in {% querystring %} (added in Django 5.1).
  • RelatedLinkColumn and NullBooleanField support removed.
  • DateColumn / DateTimeColumn / TimeColumn now export in ISO format.
  • TemplateColumn now receives request in its rendering context, gains optional context_object_name, and extra_context may be a callable. Its render() signature changed in 2.9.0 and was restored in 3.0.0.
  • Column-render argument dispatch now uses inspect.signature(..., annotation_format="string").
  • TimeColumn added; Accessor can pass args/kwargs to callables; Column.accessor set explicitly at bind time.
  • Supported: Django 5.2 / 6.0, Python 3.10-3.14. Django 4.2 and 5.1 dropped.

Breaking Changes

  1. {% querystring %} no longer exists. Verified against v3.0.0 source: the tag library registers only querystring_replace, render_table, export_url, and the localize / unlocalize / table_page_range / render_attrs filters. No back-compat alias.
  2. RelatedLinkColumn removed — use Column(linkify=True).
  3. Django < 5.2 unsupported.

Migration Notes

Rename {% querystring %} to {% querystring_replace %}, and {% load querystring from django_tables2 %} to {% load querystring_replace from django_tables2 %}.

⚠️ Two failure modes, only one of them loud. HQ's templates {% load django_tables2 %}, so the bare name now falls through to Django's built-in tag, whose signature is querystring(context, query_dict=None, **kwargs):

  • Hard failure (TemplateSyntaxError) for calls with arguments. The built-in supports neither form HQ uses:
    • {% querystring without table.prefixed_order_by_field %} → "received too many positional arguments"; the built-in has no without support.
    • {% querystring table.prefixed_page_field=p %} → "Could not parse the remainder: =p". Django's kwarg regex (?:(\w+)=)?(.+) won't match a dotted key; django-tables2's own tag resolved the key as a template variable, which is why this works today.
  • Silent change for bare calls: the built-in returns "" with no query params where django-tables2 returned "?". Most sites are hx-get="{{ request.path_info }}{% querystring %}" where either is a valid URL, but bootstrap5_htmx.html:15 is hx-replace-url="{% querystring %}", which becomes an empty attribute. Also, the built-in reads context.request (attribute) where django-tables2 read context["request"] (key) — relevant anywhere rendering uses a plain Context rather than a RequestContext.

⚠️ Impact Assessment

Breaking Changes Found: Yes.

Affected Files — hard failures (15 call sites, 3 templates)

File Lines Issue
hqwebapp/templates/hqwebapp/tables/header.html 1 {% load querystring from django_tables2 %} — fails at compile: 'querystring' is not a valid tag or filter in tag library 'django_tables2'
hqwebapp/templates/hqwebapp/tables/header.html 15, 16, 23 without form
hqwebapp/templates/hqwebapp/tables/header.html 32, 33, 40 dotted-kwarg form
hqwebapp/templates/hqwebapp/tables/bootstrap5.html 77, 95, 113 dotted-kwarg form
hqwebapp/templates/hqwebapp/tables/bootstrap5_htmx.html 40, 41, 48, 49, 61, 62 dotted-kwarg form

header.html is the blast radius — it's the target of {% render_header %} in hq_tables_tags.py, which bootstrap5.html uses for {% block table.thead %}. Every table header render fails.

Affected Files — silent change (24 bare call sites, 16 templates)

  • hqwebapp/templates/hqwebapp/tables/bootstrap5_htmx.html:14,15,34
  • data_cleaning/templates/data_cleaning/tables/bulk_edit_session.html:102,152,177; bulk_edit_session.html:45
  • data_cleaning/.../modals/confirm_apply.html:10, confirm_undo.html:10, confirm_clear.html:10, confirm_select_all.html:12
  • data_cleaning/.../status/in_progress.html:6, modal.html:22, previous_session.html:34, complete.html:33
  • data_cleaning/.../columns/selection.html:5, selection_header.html:8, column_editable.html:56,94
  • integration/templates/kyc/kyc_verify_report.html:55,68
  • integration/templates/payments/payments_verify_report.html:57,69
  • styleguide/.../bootstrap5/examples/htmx_pagination.html:34

Checked and clear

  • No RelatedLinkColumn usage. ✅
  • No DateColumn / DateTimeColumn / TimeColumn usage — hqwebapp/tables/columns.py defines DateTimeStringColumn(columns.Column) with a custom render(), so the ISO-export change doesn't affect HQ export output. ✅
  • django~=5.2.16 and requires-python = ">=3.13" are inside the supported matrix. ✅
  • render_table, export_url, table_page_range still registered, so single_table.html and the pagination ranges are otherwise fine. ✅
  • Upstream blocks HQ extends from django_tables2/bootstrap5.html (table-wrapper, table, table.thead) still exist in 3.0.0, and upstream's own querystring_replace calls sit in blocks HQ overrides. ✅

Test Impact

CI should catch the hard failures — corehq/apps/integration/payments/tests/test_views.py issues real self.client.get() calls against the payments verification table view, which renders bootstrap5_htmx.htmlheader.html. If those come back green, that's itself a signal the templates aren't rendered under test. The bare-call cases won't be caught; output just changes shape.

Two smaller things to re-verify: data_cleaning/columns.py SelectableHtmxColumn.render(self, value, bound_column, record) and integration/kyc/tables.py:23 DisableableCheckBoxColumn.render(self, value, record, bound_column) both rely on name-based argument dispatch, exactly the machinery the inspect.signature change touched; and EditableHtmxColumn.get_htmx_partial_response_context builds a BoundColumn by hand, while 2.7.1 changed when Column.accessor is set at bind time.

Configuration Changes: None. pyproject.toml leaves django-tables2 unpinned, so only uv.lock moves.


🛠️ Recommendations

Action Required (before merge)

  1. hqwebapp/templates/hqwebapp/tables/header.html:1{% load querystring_replace from django_tables2 %}
  2. Replace {% querystring with {% querystring_replace at all 39 call sites above. Every affected template already has {% load django_tables2 %}, so no other load lines change. Update the explanatory comment at styleguide/.../examples/htmx_pagination.html:33, which names the tag.

Prefer the mechanical rename over letting bare calls fall through to the built-in — it preserves current behavior exactly (including the "?" output) and avoids two near-identically-named tags behaving differently in one codebase. Alternative: register a querystring shim in hqwebapp/templatetags/hq_tables_tags.py delegating to querystring_replace (one file instead of 39 edits), but that reintroduces the shadowing this release set out to remove.

Testing Focus

  • Data Cleaning bulk edit: table render, pagination, sorting, inline cell edit, all confirm modals.
  • KYC and Payments verification reports: sorting, pagination, per-page selector.
  • Styleguide HTMX pagination example.
  • HTMX partials specifically — hx-replace-url values and the URL pushed after sort/page changes.
  • TableExportMixin exports (as_values()) for tables using a TemplateColumn, since TemplateColumn request handling changed in 2.8.0 while the export path builds its own Context({"exporting": True}).

Follow-up Tasks

  • Add a rendering test for hqwebapp/tables/header.html (sortable/non-sortable x HTMX/non-HTMX link modes). It has no direct coverage today, which is why a rename this disruptive isn't guaranteed to fail loudly.
  • TemplateColumn's new callable extra_context and context_object_name could simplify data_cleaning/columns.py later.

Merge Recommendation: HOLD — until the template migration lands with the lock bump.


📚 Useful Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file product/invisible Change has no end-user visible impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant