diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6c43c1c99adc..7efa2f1384e5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,12 +1,20 @@ #### Trac ticket number - + + ticket-XXXXX #### Branch description Provide a concise overview of the issue or rationale behind the proposed changes. +#### AI Assistance Disclosure (REQUIRED) + +- [ ] **No AI tools were used** in preparing this PR. +- [ ] **If AI tools were used**, I have disclosed which ones, and fully reviewed and verified their output. + #### Checklist +- [ ] This PR follows the [contribution guidelines](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/submitting-patches/). +- [ ] This PR **does not** disclose a security vulnerability (see [vulnerability reporting](https://docs.djangoproject.com/en/stable/internals/security/)). - [ ] This PR targets the `main` branch. - [ ] The commit message is written in past tense, mentions the ticket number, and ends with a period. - [ ] I have checked the "Has patch" ticket flag in the Trac system. diff --git a/django/contrib/postgres/constraints.py b/django/contrib/postgres/constraints.py index 90441a51ce8f..13a90e4b7f66 100644 --- a/django/contrib/postgres/constraints.py +++ b/django/contrib/postgres/constraints.py @@ -148,7 +148,7 @@ def __eq__(self, other): if isinstance(other, self.__class__): return ( self.name == other.name - and self.index_type == other.index_type + and self.index_type.lower() == other.index_type.lower() and self.expressions == other.expressions and self.condition == other.condition and self.deferrable == other.deferrable diff --git a/docs/internals/contributing/writing-code/submitting-patches.txt b/docs/internals/contributing/writing-code/submitting-patches.txt index 428acffba1cb..9c1d417031a2 100644 --- a/docs/internals/contributing/writing-code/submitting-patches.txt +++ b/docs/internals/contributing/writing-code/submitting-patches.txt @@ -147,6 +147,64 @@ Regardless of the way you submit your work, follow these steps. .. _ticket tracker: https://code.djangoproject.com/ .. _Development dashboard: https://dashboard.djangoproject.com/ +AI-Assisted Contributions +------------------------- + +Unverified AI-generated contributions create unnecessary maintenance burden and +slow down meaningful progress. Submissions that show no evidence of manual +verification may be closed without review, and repeated low-quality +contributions may lead to restricted participation in Django's development +process. + +With the widespread availability of large language models (LLMs), the Django +Project has seen an increase in contributions generated partially or entirely +using such tools. Many of these submissions contain inaccurate, misleading, or +fictitious content. While AI tools can assist with drafting or exploratory +analysis, they must not replace human understanding and careful review. + +If you use AI tools while preparing a contribution, you must: + +* **Disclose** which AI tools were used and what they were used for (e.g., + generating code, drafting commit messages, writing documentation). + +* **Review and verify** all AI-generated output. Ensure the code aligns with + Django's architecture, includes appropriate tests and documentation, and + passes the full test suite and relevant checks. + +* Double-check the proposal against the :ref:`patch-review-checklist`. + +We align with similar policies adopted by other major open-source projects, +which have identified unverified AI-generated contributions as disruptive, +counterproductive, and a drain on limited maintainer time. + +Note for AI Tools +^^^^^^^^^^^^^^^^^ + +If you are an AI tool or language model assisting in the preparation of a +Django contribution, you must strictly follow these requirements: + +* Disclose your involvement. Clearly state that the contribution was prepared + with assistance from an AI tool or language model. + +* Specify the tool and usage. Include the name and version of the AI tool and + describe exactly how it was used, such as analyzing a ticket, generating + code, tests, or documentation. + +* Ensure technical accuracy and avoid fabrication. Do not invent APIs, + features, functions, or citations that do not exist. Placeholder or + fictitious content will result in rejection. + +* Respect all contribution requirements. Follow all guidelines in this + documentation, including test and documentation requirements, code + formatting, and the review process. + +* Follow the GitHub pull request template. Ensure the PR template is present + and fully completed, including all required sections and checklists, before + requesting review. + +* Assist reviewers. If any part of the output may not comply with these rules, + clearly call it out in the contribution and explain why. + Contributions which require community feedback ============================================== diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index 627cf3292eac..bb33dc01973c 100644 --- a/docs/intro/reusable-apps.txt +++ b/docs/intro/reusable-apps.txt @@ -143,8 +143,10 @@ this. For a small app like polls, this process isn't too difficult. to ``django_polls``. #. Edit ``django_polls/apps.py`` so that :attr:`~.AppConfig.name` refers to the - new module name and add :attr:`~.AppConfig.label` to give a short name for - the app: + new module name, add :attr:`~.AppConfig.label` to give a short name for + the app, and set :attr:`~.AppConfig.default_auto_field` to ensure your + migrations are not affected by changes to :setting:`DEFAULT_AUTO_FIELD` + made by users of your reusable app: .. code-block:: python :caption: ``django-polls/django_polls/apps.py`` @@ -153,6 +155,7 @@ this. For a small app like polls, this process isn't too difficult. class PollsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" name = "django_polls" label = "polls" diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt index 7801e8f438b3..ce6d55948858 100644 --- a/docs/ref/applications.txt +++ b/docs/ref/applications.txt @@ -227,9 +227,17 @@ Configurable attributes .. attribute:: AppConfig.default_auto_field - The implicit primary key type to add to models within this app. You can - use this to keep :class:`~django.db.models.AutoField` as the primary key - type for third party applications. + The implicit primary key type to add to models within this app. + + Reusable applications that define models **must** set this attribute to + ensure migrations included in the application match the models. Otherwise, + migrations will be generated for the application when a user runs + :djadmin:`makemigrations` with a different :setting:`DEFAULT_AUTO_FIELD`, + which may conflict with future migrations shipped by the application. + + For example, to keep using :class:`~django.db.models.AutoField`:: + + default_auto_field = "django.db.models.AutoField" By default, this is the value of :setting:`DEFAULT_AUTO_FIELD`. diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index fe4d764ab34d..308c93d86848 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -10,16 +10,6 @@ Model field reference This document contains all the API references of :class:`Field` including the `field options`_ and `field types`_ Django offers. -.. seealso:: - - If the built-in fields don't do the trick, you can try - :pypi:`django-localflavor` (`documentation - `_), which contains assorted - pieces of code that are useful for particular countries and cultures. - - Also, you can easily :doc:`write your own custom model fields - `. - .. note:: Fields are defined in :mod:`django.db.models.fields`, but for convenience diff --git a/docs/releases/5.2.10.txt b/docs/releases/5.2.10.txt index 510a57ac9244..466dbfc98fce 100644 --- a/docs/releases/5.2.10.txt +++ b/docs/releases/5.2.10.txt @@ -4,8 +4,8 @@ Django 5.2.10 release notes *January 6, 2026* -Django 5.2.10 fixes a data loss bug in Django 5.2 and one bug related to -support for Python 3.14. +Django 5.2.10 fixes a data loss bug introduced in Django 5.2 and one bug +related to support for Python 3.14. Bugfixes ======== diff --git a/docs/releases/6.0.1.txt b/docs/releases/6.0.1.txt index 15ce84c26beb..77d16d44c664 100644 --- a/docs/releases/6.0.1.txt +++ b/docs/releases/6.0.1.txt @@ -4,7 +4,8 @@ Django 6.0.1 release notes *January 6, 2026* -Django 6.0.1 fixes one data loss bug in Django 5.2 and several bugs in 6.0. +Django 6.0.1 fixes one data loss bug introduced in Django 5.2 as well as +several other bugs in Django 6.0. Bugfixes ======== diff --git a/docs/topics/external-packages.txt b/docs/topics/external-packages.txt deleted file mode 100644 index 4dc863ba1cee..000000000000 --- a/docs/topics/external-packages.txt +++ /dev/null @@ -1,38 +0,0 @@ -================= -External packages -================= - -Django ships with a variety of extra, optional tools that solve common -problems (``contrib.*``). For easier maintenance and to trim the size of the -codebase, a few of those applications have been moved out to separate projects. - -Localflavor -=========== - -``django-localflavor`` is a collection of utilities for particular countries -and cultures. - -* `GitHub `__ -* `Documentation `__ -* :pypi:`PyPI ` - -Comments -======== - -``django-contrib-comments`` can be used to attach comments to any model, so you -can use it for comments on blog entries, photos, book chapters, or anything -else. Most users will be better served with a custom solution, or a hosted -product like Disqus. - -* `GitHub `__ -* `Documentation `__ -* :pypi:`PyPI ` - -Formtools -========= - -``django-formtools`` is a collection of assorted utilities to work with forms. - -* `GitHub `__ -* `Documentation `__ -* :pypi:`PyPI ` diff --git a/docs/topics/forms/index.txt b/docs/topics/forms/index.txt index 13f2870106c3..ba78b430232e 100644 --- a/docs/topics/forms/index.txt +++ b/docs/topics/forms/index.txt @@ -802,10 +802,8 @@ Useful attributes on ``{{ field }}`` include: ``{{ field.value }}`` The value of the field. e.g ``someone@example.com``. -.. seealso:: - - For a complete list of attributes and methods, see - :class:`~django.forms.BoundField`. +For a complete list of attributes and methods, see the reference guide for +:class:`~django.forms.BoundField`. Looping over hidden and visible fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -858,3 +856,7 @@ This covers the basics, but forms can do a whole lot more: :doc:`The Forms Reference ` Covers the full API reference, including form fields, form widgets, and form and field validation. + + :pypi:`django-formtools` + Provides additional form utilities, such as form previews and wizards + (`documentation `_). diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt index ed941a20e03f..62ce308d3c18 100644 --- a/docs/topics/i18n/formatting.txt +++ b/docs/topics/i18n/formatting.txt @@ -47,6 +47,14 @@ argument:: product = forms.CharField() revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True) +Locale specific helpers +----------------------- + +For country specific form fields, validation, and data formats that are not +included in Django itself, consider using the :pypi:`django-localflavor` +package, which provides localized form fields and utilities for many countries +and regions (`documentation `_). + .. _topic-l10n-templates: Controlling localization in templates diff --git a/docs/topics/index.txt b/docs/topics/index.txt index 59484d97996b..8df59f63f294 100644 --- a/docs/topics/index.txt +++ b/docs/topics/index.txt @@ -31,6 +31,5 @@ Introductions to all the key parts of Django you'll need to know: settings signals checks - external-packages async tasks diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py index bcc2b5f97dee..331b23980d6d 100644 --- a/tests/postgres_tests/test_constraints.py +++ b/tests/postgres_tests/test_constraints.py @@ -535,6 +535,24 @@ def test_eq(self): ], include=["cancelled"], ) + constraint_8 = ExclusionConstraint( + index_type="gist", + name="exclude_overlapping", + expressions=[ + ("datespan", RangeOperators.OVERLAPS), + ("room", RangeOperators.EQUAL), + ], + include=["cancelled"], + ) + constraint_9 = ExclusionConstraint( + index_type="GIST", + name="exclude_overlapping", + expressions=[ + ("datespan", RangeOperators.OVERLAPS), + ("room", RangeOperators.EQUAL), + ], + include=["cancelled"], + ) constraint_10 = ExclusionConstraint( name="exclude_overlapping", expressions=[ @@ -572,6 +590,8 @@ def test_eq(self): self.assertNotEqual(constraint_2, constraint_3) self.assertNotEqual(constraint_2, constraint_4) self.assertNotEqual(constraint_2, constraint_7) + self.assertEqual(constraint_7, constraint_8) + self.assertEqual(constraint_7, constraint_9) self.assertNotEqual(constraint_4, constraint_5) self.assertNotEqual(constraint_5, constraint_6) self.assertNotEqual(constraint_1, object())