Question: Migrations tries to add constraint before adding a foreign key. Description (last modified by Raphael Beekmann) Hello, I have a model, already created through previous migrations, and in a new migration I a new field with an UniqueConstraint. The migrations script try to create the constraint first and then the new field, resulting an error : NewModel has no field named 'category' To reproduce the bug : Create a project with two models linked together with a One-to-Many relation and an unique constraint : class Type(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), ) Create a migration file with makemigrations Add a new model with another One-to-Many relation and unique constraint. The models looks like this : class Type(models.Model): name = models.CharField(maxlength=10) class Category(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) category = models.ForeignKey(Category, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ) Create a new migration file. The order of the migration's steps are incorrect and the migration crash : class Migration(migrations.Migration): dependencies = [ ('app', '0001initial'), ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigAutoField(autocreated=True, primarykey=True, serialize=False, verbosename='ID')), ('name', models.CharField(maxlength=10)), ], ), migrations.AddConstraint( modelname='model', constraint=models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ), migrations.AddField( modelname='model', name='category', field=models.ForeignKey(null=True, , to='app.category'), ), ]

model_name=model_name,                         index=index,                     ),<ins>                    dependencies=dependencies,</ins>                 )      def generate_removed_indexes(self):


Question: Migrations tries to add constraint before adding a foreign key. Description (last modified by Raphael Beekmann) Hello, I have a model, already created through previous migrations, and in a new migration I a new field with an UniqueConstraint. The migrations script try to create the constraint first and then the new field, resulting an error : NewModel has no field named 'category' To reproduce the bug : Create a project with two models linked together with a One-to-Many relation and an unique constraint : class Type(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), ) Create a migration file with makemigrations Add a new model with another One-to-Many relation and unique constraint. The models looks like this : class Type(models.Model): name = models.CharField(maxlength=10) class Category(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) category = models.ForeignKey(Category, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ) Create a new migration file. The order of the migration's steps are incorrect and the migration crash : class Migration(migrations.Migration): dependencies = [ ('app', '0001initial'), ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigAutoField(autocreated=True, primarykey=True, serialize=False, verbosename='ID')), ('name', models.CharField(maxlength=10)), ], ), migrations.AddConstraint( modelname='model', constraint=models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ), migrations.AddField( modelname='model', name='category', field=models.ForeignKey(null=True, , to='app.category'), ), ]

app_label,             model_name,         ), alt_constraints in self.altered_constraints.items():<ins>            dependencies = self._get_dependencies_for_model(app_label, model_name)</ins>             for constraint in alt_constraints["added_constraints"]:                 self.add_operation(                     app_label,


Question: Migrations tries to add constraint before adding a foreign key. Description (last modified by Raphael Beekmann) Hello, I have a model, already created through previous migrations, and in a new migration I a new field with an UniqueConstraint. The migrations script try to create the constraint first and then the new field, resulting an error : NewModel has no field named 'category' To reproduce the bug : Create a project with two models linked together with a One-to-Many relation and an unique constraint : class Type(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), ) Create a migration file with makemigrations Add a new model with another One-to-Many relation and unique constraint. The models looks like this : class Type(models.Model): name = models.CharField(maxlength=10) class Category(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) category = models.ForeignKey(Category, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ) Create a new migration file. The order of the migration's steps are incorrect and the migration crash : class Migration(migrations.Migration): dependencies = [ ('app', '0001initial'), ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigAutoField(autocreated=True, primarykey=True, serialize=False, verbosename='ID')), ('name', models.CharField(maxlength=10)), ], ), migrations.AddConstraint( modelname='model', constraint=models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ), migrations.AddField( modelname='model', name='category', field=models.ForeignKey(null=True, , to='app.category'), ), ]

model_name=model_name,                         constraint=constraint,                     ),<ins>                    dependencies=dependencies,</ins>                 )      def generate_removed_constraints(self):


Question: Migrations tries to add constraint before adding a foreign key. Description (last modified by Raphael Beekmann) Hello, I have a model, already created through previous migrations, and in a new migration I a new field with an UniqueConstraint. The migrations script try to create the constraint first and then the new field, resulting an error : NewModel has no field named 'category' To reproduce the bug : Create a project with two models linked together with a One-to-Many relation and an unique constraint : class Type(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), ) Create a migration file with makemigrations Add a new model with another One-to-Many relation and unique constraint. The models looks like this : class Type(models.Model): name = models.CharField(maxlength=10) class Category(models.Model): name = models.CharField(maxlength=10) class Model(models.Model): name = models.CharField(maxlength=10) type = models.ForeignKey(Type, ondelete=models.SETNULL, null=True) category = models.ForeignKey(Category, ondelete=models.SETNULL, null=True) date = models.DateField(autonow=True) class Meta: constraints = ( models.UniqueConstraint(fields=('date', 'type'), name='uniquetypefordate'), models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ) Create a new migration file. The order of the migration's steps are incorrect and the migration crash : class Migration(migrations.Migration): dependencies = [ ('app', '0001initial'), ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigAutoField(autocreated=True, primarykey=True, serialize=False, verbosename='ID')), ('name', models.CharField(maxlength=10)), ], ), migrations.AddConstraint( modelname='model', constraint=models.UniqueConstraint(fields=('date', 'category'), name='uniquecategoryfordate'), ), migrations.AddField( modelname='model', name='category', field=models.ForeignKey(null=True, , to='app.category'), ), ]

dependencies.append((through_app_label, through_object_name, None, True))         return dependencies <ins>    def _get_dependencies_for_model(self, app_label, model_name):        """Return foreign key dependencies of the given model."""        dependencies = []        model_state = self.to_state.models[app_label, model_name]        for field in model_state.fields.values():            if field.is_relation:                dependencies.extend(                    self._get_dependencies_for_foreign_key(                        app_label,                        model_name,                        field,                        self.to_state,                    )                )        return dependencies</ins>     def _get_altered_foo_together_operations(self, option_name):         for app_label, model_name in sorted(self.kept_model_keys):             old_model_name = self.renamed_models.get(


Question: Improper guessing of Mime Type for "br" and "Z" file types Description Below FileResponse will set the content type as text/html, even if the last file extension is "Z' or "br". FileResponse(open('', 'rb')) FileResponse(open('', 'rb'))

# Encoding isn't set to prevent browsers from automatically                 # uncompressing files.                 content_type = {                    "br": "application/x-brotli",                     "bzip2": "application/x-bzip",                    "compress": "application/x-compress",                     "gzip": "application/gzip",                     "xz": "application/x-xz",                 }.get(encoding, content_type)


Question: Querysets: annotate() columns are forced into a certain position which may disrupt union() Description (Reporting possible issue found by a user on #django) Using values() to force selection of certain columns in a certain order proved useful unioning querysets with union() for the aforementioned user. The positioning of columns with annotate() is not controllable with values() and has the potential to disrupt union() unless this fact is known and the ordering done in a certain way to accommodate it. I'm reporting this mainly for posterity but also as a highlight that perhaps this should be mentioned in the documentation. I'm sure there are reasons why the annotations are appended to the select but if someone feels that this is changeable then it would be a bonus outcome.

if select:             self.append_annotation_mask([alias])         else:            self.set_annotation_mask(set(self.annotation_select).difference({alias}))            annotation_mask = (                value                for value in dict.fromkeys(self.annotation_select)                if value != alias            )            self.set_annotation_mask(annotation_mask)         self.annotations[alias] = annotation      def resolve_expression(self, query, *args, **kwargs):


Question: Querysets: annotate() columns are forced into a certain position which may disrupt union() Description (Reporting possible issue found by a user on #django) Using values() to force selection of certain columns in a certain order proved useful unioning querysets with union() for the aforementioned user. The positioning of columns with annotate() is not controllable with values() and has the potential to disrupt union() unless this fact is known and the ordering done in a certain way to accommodate it. I'm reporting this mainly for posterity but also as a highlight that perhaps this should be mentioned in the documentation. I'm sure there are reasons why the annotations are appended to the select but if someone feels that this is changeable then it would be a bonus outcome.

if names is None:             self.annotation_select_mask = None         else:            self.annotation_select_mask = set(names)            self.annotation_select_mask = list(dict.fromkeys(names))         self._annotation_select_cache = None      def append_annotation_mask(self, names):         if self.annotation_select_mask is not None:            self.set_annotation_mask(self.annotation_select_mask.union(names))            self.set_annotation_mask((*self.annotation_select_mask, *names))      def set_extra_mask(self, names):         """


Question: Querysets: annotate() columns are forced into a certain position which may disrupt union() Description (Reporting possible issue found by a user on #django) Using values() to force selection of certain columns in a certain order proved useful unioning querysets with union() for the aforementioned user. The positioning of columns with annotate() is not controllable with values() and has the potential to disrupt union() unless this fact is known and the ordering done in a certain way to accommodate it. I'm reporting this mainly for posterity but also as a highlight that perhaps this should be mentioned in the documentation. I'm sure there are reasons why the annotations are appended to the select but if someone feels that this is changeable then it would be a bonus outcome.

return {}         elif self.annotation_select_mask is not None:             self._annotation_select_cache = {                k: v                for k, v in self.annotations.items()                if k in self.annotation_select_mask                k: self.annotations[k]                for k in self.annotation_select_mask                if k in self.annotations             }             return self._annotation_select_cache         else:


Question: () on querysets in descending order by annotations. Description When I execute Model.objects.annotate(messagelength=Length('message')).orderby('-messagelength').update(text="Can I come on board?") I get the error FieldError: Cannot resolve keyword 'messagelength' into field. Choices are: message, id, text, x because the code ignores the descending case.

"update.tests.AdvancedTests."                 "test_update_ordered_by_inline_m2m_annotation",                 "update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation",                "update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation_desc",             },         }         if self.connection.mysql_is_mariadb and (diff --git a/django/db/models/query.py b/django/db/models/query.py-- a/django/db/models/query.py++ b/django/db/models/query.py


Question: () on querysets in descending order by annotations. Description When I execute Model.objects.annotate(messagelength=Length('message')).orderby('-messagelength').update(text="Can I come on board?") I get the error FieldError: Cannot resolve keyword 'messagelength' into field. Choices are: message, id, text, x because the code ignores the descending case.

# Inline annotations in order_by(), if possible.         new_order_by = []         for col in query.order_by:            if annotation := query.annotations.get(col):            alias = col            descending = False            if isinstance(alias, str) and alias.startswith("-"):                alias = alias.removeprefix("-")                descending = True            if annotation := query.annotations.get(alias):                 if getattr(annotation, "contains_aggregate", False):                     raise exceptions.FieldError(                         f"Cannot update when ordering by an aggregate: {annotation}"                     )                if descending:                    annotation = annotation.desc()                 new_order_by.append(annotation)             else:                 new_order_by.append(col)


Question: ModelAdmin.lookupallowed() incorrectly raises DisallowedModelAdminLookup lookup with foreign key as primary key Description (last modified by Tim Graham) Wrote a failing test for to demonstrate - same test/code passes on 1.8 def testlookupallowedforeignprimary(self): class Country(models.Model): name = models.CharField(maxlength=256) class Place(models.Model): country = models.ForeignKey(Country, models.CASCADE) class Restaurant(models.Model): place = models.OneToOneField(Place, models.CASCADE, primarykey=True) class Waiter(models.Model): restaurant = models.ForeignKey(Restaurant, models.CASCADE) class WaiterAdmin(ModelAdmin): listfilter = [ 'restaurantplacecountry', ] ma = WaiterAdmin(Waiter, ) self.assertIs(ma.lookupallowed('restaurantplacecountry', 'testvalue'), True) I think this is caused by the admin thinking that having a foreign key field as a primary key is the same as concrete inheritance. So when you try and check lookups for restaurantplacecountry it thinks 'place' is the concrete parent of 'restaurant' and shortcuts it to restaurantcountry which isn't in 'listfilter'. And you can't add restaurantcountry to list_filter because country isn't actually on restaurant.

# Lookups on nonexistent fields are ok, since they're ignored                 # later.                 break            # It is allowed to filter on values that would be found from local            # model anyways. For example, if you filter on employee__department__id,            # then the id value would be found already from employee__department_id.             if not prev_field or (                 prev_field.is_relation                and field not in prev_field.path_infos[-1].target_fields                and field not in model._meta.parents.values()                and field is not model._meta.auto_field                and (                    model._meta.auto_field is None                    or part not in getattr(prev_field, "to_fields", [])                )             ):                 relation_parts.append(part)             if not getattr(field, "path_infos", None):


Question: Migration import ordering violates coding style and isort defaults Description New migration files are generated with imports sorted by module, independent of import style. For example: import datetime from import migrations, models import time The Django coding style specifies: Place all import module statements before from module import objects in each section. This guidance is the same as what isort does by default, as documented here. Newly generated migrations can fail isort for this reason. This would mean migration files should instead be generated like this: import datetime import time from import migrations, models For reference, previous issues related to migration import sorting: , .

# Sort imports by the package / module to be imported (the part after         # "from" in "from ... import ..." or after "import" in "import ...").        sorted_imports = sorted(imports, key=lambda i: i.split()[1])        # First group the "import" statements, then "from ... import ...".        sorted_imports = sorted(            imports, key=lambda i: (i.split()[0] == "from", i.split()[1])        )         items["imports"] = "\n".join(sorted_imports) + "\n" if imports else ""         if migration_imports:             items["imports"] += (


Question: SelectDateWidget can crash with OverflowError. Description Given a relatively common view like this: from django import forms from import SelectDateWidget from import HttpResponse class ReproForm(forms.Form): mydate = forms.DateField(widget=SelectDateWidget()) def reproview(request): form = ReproForm(request.GET) # for ease of reproducibility if form.isvalid(): return HttpResponse("ok") else: return HttpResponse("not ok") urlpatterns = [path('repro/', views.reproview, name='repro')] A user can trigger a server crash, reproducible by running locally and visiting http://127.0.0.1:8000/repro/?mydateday=1&mydatemonth=1&mydateyear=, which results in [...] - ERROR - django.request: Internal Server Error: /repro/ Traceback (most recent call last): [...] File "[...]/site-", line 1160, in valuefromdatadict datevalue = (int(y), int(m), int(d)) OverflowError: signed integer is greater than maximum This can be triggered similarly for a post request. The issue happens as part of the validation logic run in form.isvalid, specifically, when calling the SelectDateWidget.valuefromdatadict, where the user-controlled value is converted into a date without guarding against a possible OverflowError. Specifically, y, m and d are user controlled, and the code does this: date_value = (int(y), int(m), int(d)) When large integers (larger than sys.maxsize) are supplied to date's constructor it will throw an OverflowError: import datetime, sys (sys.maxsize+1, 3, 4) Traceback (most recent call last): File "<stdin", line 1, in <moduleOverflowError: Python int too large to convert to C long

# Return pseudo-ISO dates with zeros for any unselected values,                 # e.g. '2017-0-23'.                 return "%s-%s-%s" % (y or 0, m or 0, d or 0)<ins>            except OverflowError:                return "0-0-0"</ins>             return date_value.strftime(input_format)         return data.get(name)


Question: ASGIStaticFilesHandler raises warning. Description (last modified by Carlton Gibson) async support to StreamingHttpResponse for Django 4.2. With Django 4.2rc1 and Daphne, ASGIStaticFilesHandler raises a warning about the incorrect iterator type being used: Warning: StreamingHttpResponse must consume synchronous iterators in order to serve them asynchronously. Use an asynchronous iterator instead. This is because FileResponse is not async compatible (nor is that likely, since neither is open()). A new project with: INSTALLEDAPPS = [ "daphne", ... ] ASGIAPPLICATION = "" runserver, and then visit any page serving static files such as /admin/. The fix is to have ASGIStaticFilesHandler adapt the iterator in the same way StreamingHttpResponse does.

async def get_response_async(self, request):         response = await super().get_response_async(request)         response._resource_closers.append(request.close)<ins>        # FileResponse is not async compatible.        if response.streaming and not response.is_async:            _iterator = response.streaming_content            async def awrapper():                for part in await sync_to_async(list)(_iterator):                    yield part            response.streaming_content = awrapper()</ins>         return response


Question: values() doesn't mention annotations as valid choices on resolving error Description When doing Book.objects.annotate(annotation=Value(1)).values("annotationtype") The resulting FieldError doesn't mention annotation as a valid choice FieldError: Cannot resolve keyword 'annotationtypo' into field. Choices are: age, book, bookcontactset, friends, id, name

# For lookups spanning over relationships, show the error                 # from the model on which the lookup failed.                 raise<del>            elif name in self.annotations:                raise FieldError(                    "Cannot select the '%s' alias. Use annotate() to promote "                    "it." % name                )</del>             else:                 names = sorted(                     [


Question: values() doesn't mention annotations as valid choices on resolving error Description When doing Book.objects.annotate(annotation=Value(1)).values("annotationtype") The resulting FieldError doesn't mention annotation as a valid choice FieldError: Cannot resolve keyword 'annotationtypo' into field. Choices are: age, book, bookcontactset, friends, id, name

extra_names.append(f)                     elif f in self.annotation_select:                         annotation_names.append(f)                    elif f in self.annotations:                        raise FieldError(                            f"Cannot select the '{f}' alias. Use annotate() to "                            "promote it."                        )                     else:                        # Call `names_to_path` to ensure a FieldError including                        # annotations about to be masked as valid choices if                        # `f` is not resolvable.                        if self.annotation_select:                            self.names_to_path(f.split(LOOKUP_SEP), self.model._meta)                         field_names.append(f)             self.set_extra_mask(extra_names)             self.set_annotation_mask(annotation_names)


Question: Improve error message for incorrect context processors Description If you write a template context processor but return the wrong type, for example None by missing the return statement: def data(request): data = {"something": True} Then currently the error message is very mysterious: Internal Server Error: / Traceback (most recent call last): ... File "/..../site-", line 61, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/..../site-", line 173, in render with context.bindtemplate(self): File "", line 137, in enter return next() ^^^^^^^^^^^^^^ File "/..../site-", line 254, in bindtemplate (processor(self.request)) TypeError: 'NoneType' object is not iterable If a view returns the wrong type, Django raises a nice error message: The view didn't return an HttpResponse object. It returned None instead. I suggest we do the same for context processors. If we use try/except around the () line, it will not slow down normal processing any noticeable amount, thanks to Python 3.11's “zero-cost” exception handling:

processors = template.engine.template_context_processors + self._processors         updates = {}         for processor in processors:            updates.update(processor(self.request))            context = processor(self.request)            try:                updates.update(context)            except TypeError as e:                raise TypeError(                    f"Context processor {processor.__qualname__} didn't return a "                    "dictionary."                ) from e         self.dicts[self._processors_index] = updates          try:


Question: DateField.inputformats cannot be printed Description I am trying to display the input formats for This seems to fail at the moment when using str, while repr works. Example code: from import DateField print(repr(DateField().inputformats)) print(DateField().input_formats) This will result in the following error: Traceback (most recent call last): File "<console", line 1, in <moduleTypeError: str returned non-string (type list) I would have expected the string representation to be available as well instead of failing with an internal Python error.

raise ValueError(                     "Cannot call lazy() with both bytes and text return types."                 )            if cls._delegate_text:                cls.__str__ = cls.__text_cast            elif cls._delegate_bytes:            if cls._delegate_bytes:                 cls.__bytes__ = cls.__bytes_cast          @classmethod


Question: DateField.inputformats cannot be printed Description I am trying to display the input formats for This seems to fail at the moment when using str, while repr works. Example code: from import DateField print(repr(DateField().inputformats)) print(DateField().input_formats) This will result in the following error: Traceback (most recent call last): File "<console", line 1, in <moduleTypeError: str returned non-string (type list) I would have expected the string representation to be available as well instead of failing with an internal Python error.

return __wrapper__         def __text_cast(self):            return func(*self.__args, **self.__kw)         def __bytes_cast(self):             return bytes(func(*self.__args, **self.__kw))         def __bytes_cast_encoded(self):            return func(*self.__args, **self.__kw).encode()         def __cast(self):             if self._delegate_bytes:                 return self.__bytes_cast()            elif self._delegate_text:                return self.__text_cast()             else:                 return func(*self.__args, **self.__kw)


Question: i18npatterns() not respecting prefixdefaultlanguage=False Description (last modified by Oussama Jarrousse) In my django project file I have the following setup: from import i18npatterns from django.contrib import admin from import include from import path urlpatterns = [] urlpatterns += i18npatterns( path("admin/", ), prefixdefaultlanguage=False ) In versions Django==4.1.7 (or prior), I was able to navigating to /admin/ without having to add the language prefix. Django==4.2.0, navigating to /admin/ will cause a HTTP 302 and only /en/admin/ works... although prefixdefault_language=False is explicitly defined. This change broke my API upon backend packages upgrade from 4.1.7 to 4.2.0

from django.utils.functional import cached_property from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes from django.utils.regex_helper import _lazy_re_compile, normalizefrom django.utils.translation import get_languagefrom django.utils.translation import get_language, get_supported_language_variant  from .converters import get_converter from .exceptions import NoReverseMatch, Resolver404


Question: i18npatterns() not respecting prefixdefaultlanguage=False Description (last modified by Oussama Jarrousse) In my django project file I have the following setup: from import i18npatterns from django.contrib import admin from import include from import path urlpatterns = [] urlpatterns += i18npatterns( path("admin/", ), prefixdefaultlanguage=False ) In versions Django==4.1.7 (or prior), I was able to navigating to /admin/ without having to add the language prefix. Django==4.2.0, navigating to /admin/ will cause a HTTP 302 and only /en/admin/ works... although prefixdefault_language=False is explicitly defined. This change broke my API upon backend packages upgrade from 4.1.7 to 4.2.0

@property     def language_prefix(self):         language_code = get_language() or settings.LANGUAGE_CODE        if language_code == settings.LANGUAGE_CODE and not self.prefix_default_language:        default_language = get_supported_language_variant(settings.LANGUAGE_CODE)        if language_code == default_language and not self.prefix_default_language:             return ""         else:             return "%s/" % language_codediff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py-- a/django/utils/translation/__init__.py++ b/django/utils/translation/__init__.py


Question: i18npatterns() not respecting prefixdefaultlanguage=False Description (last modified by Oussama Jarrousse) In my django project file I have the following setup: from import i18npatterns from django.contrib import admin from import include from import path urlpatterns = [] urlpatterns += i18npatterns( path("admin/", ), prefixdefaultlanguage=False ) In versions Django==4.1.7 (or prior), I was able to navigating to /admin/ without having to add the language prefix. Django==4.2.0, navigating to /admin/ will cause a HTTP 302 and only /en/admin/ works... although prefixdefault_language=False is explicitly defined. This change broke my API upon backend packages upgrade from 4.1.7 to 4.2.0

"get_language_from_request",     "get_language_info",     "get_language_bidi",<ins>    "get_supported_language_variant",</ins>     "check_for_language",     "to_language",     "to_locale",


Question: StepValueValidator does not take into account minvalue Description If you define a number input with <input type="number" min=1 step=2, client side this will only allow positive odd numbers. We could generate the same input in a Django form with IntegerField(minvalue=1, stepsize=2) and Field.localize is False, which would then use MinValueValidator and StepValueValidator. We then get into a problem as StepValueValidator always uses 0 as the base, so stepsize=2 only even numbers are allowed. This then conflicts with the client side validation, and the user cannot submit any value for the input. I'm unsure if this is a bug or whether this is just a configuration problem, apologies if so, but the behaviour does seem to me to conflict with how min and step is handled by browsers.

message = _("Ensure this value is a multiple of step size %(limit_value)s.")     code = "step_size"     def __init__(self, limit_value, message=None, offset=None):        super().__init__(limit_value, message)        if offset is not None:            self.message = _(                "Ensure this value is a multiple of step size %(limit_value)s, "                "starting from %(offset)s, e.g. %(offset)s, %(valid_value1)s, "                "%(valid_value2)s, and so on."            )        self.offset = offset    def __call__(self, value):        if self.offset is None:            super().__call__(value)        else:            cleaned = self.clean(value)            limit_value = (                self.limit_value() if callable(self.limit_value) else self.limit_value            )            if self.compare(cleaned, limit_value):                offset = cleaned.__class__(self.offset)                params = {                    "limit_value": limit_value,                    "offset": offset,                    "valid_value1": offset + limit_value,                    "valid_value2": offset + 2 * limit_value,                }                raise ValidationError(self.message, code=self.code, params=params)     def compare(self, a, b):        return not math.isclose(math.remainder(a, b), 0, abs_tol=1e-9)        offset = 0 if self.offset is None else self.offset        return not math.isclose(math.remainder(a - offset, b), 0, abs_tol=1e-9)   @deconstructiblediff --git a/django/forms/fields.py b/django/forms/fields.py-- a/django/forms/fields.py++ b/django/forms/fields.py


Question: StepValueValidator does not take into account minvalue Description If you define a number input with <input type="number" min=1 step=2, client side this will only allow positive odd numbers. We could generate the same input in a Django form with IntegerField(minvalue=1, stepsize=2) and Field.localize is False, which would then use MinValueValidator and StepValueValidator. We then get into a problem as StepValueValidator always uses 0 as the base, so stepsize=2 only even numbers are allowed. This then conflicts with the client side validation, and the user cannot submit any value for the input. I'm unsure if this is a bug or whether this is just a configuration problem, apologies if so, but the behaviour does seem to me to conflict with how min and step is handled by browsers.

if min_value is not None:             self.validators.append(validators.MinValueValidator(min_value))         if step_size is not None:            self.validators.append(validators.StepValueValidator(step_size))            self.validators.append(                validators.StepValueValidator(step_size, offset=min_value)            )      def to_python(self, value):         """


Question: Error messages customization and internationalization in Paginator class Description There is no ability to change error messages raised by Paginator.validate_number method.

# Translators: String used to replace omitted page numbers in elided page     # range generated by paginators, e.g. [1, 2, '…', 5, 6, 7, '…', 9, 10].     ELLIPSIS = _("…")    def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True):    default_error_messages = {        "invalid_page": _("That page number is not an integer"),        "min_page": _("That page number is less than 1"),        "no_results": _("That page contains no results"),    }    def __init__(        self,        object_list,        per_page,        orphans=0,        allow_empty_first_page=True,        error_messages=None,    ):         self.object_list = object_list         self._check_object_list_is_ordered()         self.per_page = int(per_page)         self.orphans = int(orphans)         self.allow_empty_first_page = allow_empty_first_page        self.error_messages = (            self.default_error_messages            if error_messages is None            else self.default_error_messages | error_messages        )      def __iter__(self):         for page_number in self.page_range:


Question: Error messages customization and internationalization in Paginator class Description There is no ability to change error messages raised by Paginator.validate_number method.

raise ValueError             number = int(number)         except (TypeError, ValueError):            raise PageNotAnInteger(_("That page number is not an integer"))            raise PageNotAnInteger(self.error_messages["invalid_page"])         if number < 1:            raise EmptyPage(_("That page number is less than 1"))            raise EmptyPage(self.error_messages["min_page"])         if number > self.num_pages:            raise EmptyPage(_("That page contains no results"))            raise EmptyPage(self.error_messages["no_results"])         return number      def get_page(self, number):


Question: ASGIRequest doesn't respect settings.FORCESCRIPTNAME. Description For example, I have settings.FORCESCRIPTNAME = '/some-prefix' I start a django server with command: daphne And I navigate to the http://localhost:8000/admin/login, and see the login form action url is "/admin/login" which is wrong, which should be "/some-prefix/admin/login"

logger = logging.getLogger("django.request")  <ins>def get_script_prefix(scope):    """    Return the script prefix to use from either the scope or a setting.    """    if settings.FORCE_SCRIPT_NAME:        return settings.FORCE_SCRIPT_NAME    return scope.get("root_path", "") or ""</ins> class ASGIRequest(HttpRequest):     """     Custom request subclass that decodes from an ASGI-standard request dict


Question: ASGIRequest doesn't respect settings.FORCESCRIPTNAME. Description For example, I have settings.FORCESCRIPTNAME = '/some-prefix' I start a django server with command: daphne And I navigate to the http://localhost:8000/admin/login, and see the login form action url is "/admin/login" which is wrong, which should be "/some-prefix/admin/login"

self._post_parse_error = False         self._read_started = False         self.resolver_match = None        self.script_name = self.scope.get("root_path", "")        self.script_name = get_script_prefix(scope)         if self.script_name:             # TODO: Better is-prefix checking, slash handling?             self.path_info = scope["path"].removeprefix(self.script_name)


Question: ASGIRequest doesn't respect settings.FORCESCRIPTNAME. Description For example, I have settings.FORCESCRIPTNAME = '/some-prefix' I start a django server with command: daphne And I navigate to the http://localhost:8000/admin/login, and see the login form action url is "/admin/login" which is wrong, which should be "/some-prefix/admin/login"

except RequestAborted:             return         # Request is complete and can be served.        set_script_prefix(self.get_script_prefix(scope))        set_script_prefix(get_script_prefix(scope))         await signals.request_started.asend(sender=self.__class__, scope=scope)         # Get the request and check for basic issues.         request, error_response = self.create_request(scope, body_file)


Question: ASGIRequest doesn't respect settings.FORCESCRIPTNAME. Description For example, I have settings.FORCESCRIPTNAME = '/some-prefix' I start a django server with command: daphne And I navigate to the http://localhost:8000/admin/login, and see the login form action url is "/admin/login" which is wrong, which should be "/some-prefix/admin/login"

(position + cls.chunk_size) >= len(data),             )             position += cls.chunk_size<del>    def get_script_prefix(self, scope):        """        Return the script prefix to use from either the scope or a setting.        """        if settings.FORCE_SCRIPT_NAME:            return settings.FORCE_SCRIPT_NAME        return scope.get("root_path", "") or ""</del>


Question: Annotating with Chr raises ValueError Description (last modified by Jacob Walls) Author.objects.annotate(firstletter=Chr(Value(77))) File "", line 369, in <lambdaelse int(value) ValueError: invalid literal for int() with base 10: 'M' I'm suggesting in Chr we can set outputfield = CharField() to prevent this.

class Chr(Transform):     function = "CHR"     lookup_name = "chr"<ins>    output_field = CharField()</ins>      def as_mysql(self, compiler, connection, **extra_context):         return super().as_sql(


Question: Admin check for reversed foreign key used in "listdisplay" Description Currently the admin site checks and reports an admin.E109 system check error when a ManyToManyField is declared within the listdisplay values. But, when a reversed foreign key is used there is no system error reported: System check identified no issues (0 silenced). April 10, 2023 - 19:04:29 Django version 5.0.dev20230410064954, using settings 'projectfromrepo.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C. and visiting the admin site for the relevant model results in the following error: TypeError: createreversemanytoonemanager.() missing 1 required keyword-only argument: 'manager' [10/Apr/2023 19:30:40] "GET /admin/testapp/question/ HTTP/1.1" 500 Ideally, using a reversed foreign key would also result in a system check error instead of a 500 response. To reproduce, follow the Question and Choice models from the Django Tutorial and add the following to the QuestionAdmin: listdisplay = ["questiontext", "choiceset"] Then, visit /admin/testapp/question/ and the following traceback is returned: Internal Server Error: /admin/testapp/question/ Traceback (most recent call last): File "", line 681, in getfield return self.fieldsmap[fieldname] ~~~^^^^^^^^^^^^ KeyError: 'choiceset' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 288, in lookupfield f = getnongfkfield(opts, name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 319, in getnongfkfield field = opts.getfield(name) ^^^^^^^^^^^^^^^^^^^^ File "", line 683, in getfield raise FieldDoesNotExist( Question has no field named 'choiceset' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 55, in inner response = getresponse(request) ^^^^^^^^^^^^^^^^^^^^^ File "", line 220, in getresponse response = () ^^^^^^^^^^^^^^^^^ File "", line 111, in render self.content = self.renderedcontent ^^^^^^^^^^^^^^^^^^^^^ File "", line 89, in renderedcontent return (context, self.request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 61, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 171, in render return (context) ^^^^^^^^^^^^^^^^^^^^^ File "", line 163, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in render return SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 962, in renderannotated return (context) ^^^^^^^^^^^^^^^^^^^^ File "", line 157, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 163, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in render return SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 962, in renderannotated return (context) ^^^^^^^^^^^^^^^^^^^^ File "", line 157, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 163, in render return (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in render return SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 962, in renderannotated return (context) ^^^^^^^^^^^^^^^^^^^^ File "", line 63, in render result = (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in render return SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 962, in renderannotated return (context) ^^^^^^^^^^^^^^^^^^^^ File "", line 63, in render result = (context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in render return SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1001, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 962, in renderannotated return (context) ^^^^^^^^^^^^^^^^^^^^ File "", line 45, in render return super().render(context) ^^^^^^^^^^^^^^^^^^^^^^^ File "", line 258, in render dict = (resolvedargs, resolvedkwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 340, in resultlist "results": list(results(cl)), ^^^^^^^^^^^^^^^^^ File "", line 316, in results yield ResultList(None, itemsforresult(cl, res, None)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 307, in init super().init(items) File "", line 217, in itemsforresult f, attr, value = lookupfield(fieldname, result, cl.modeladmin) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 301, in lookupfield value = attr() ^^^^^^ TypeError: createreversemanytoonemanager.() missing 1 required keyword-only argument: 'manager' [10/Apr/2023 19:30:40] "GET /admin/testapp/question/ HTTP/1.1" 500

id="admin.E108",                     )                 ]        if isinstance(field, models.ManyToManyField):        if isinstance(field, models.ManyToManyField) or (            getattr(field, "rel", None) and field.rel.field.many_to_one        ):             return [                 checks.Error(                    "The value of '%s' must not be a ManyToManyField." % label,                    f"The value of '{label}' must not be a many-to-many field or a "                    f"reverse foreign key.",                     obj=obj.__class__,                     id="admin.E109",                 )


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

else self.get_list_display(request)         )     def lookup_allowed(self, lookup, value):    # RemovedInDjango60Warning: when the deprecation ends, replace with:    # def lookup_allowed(self, lookup, value, request):    def lookup_allowed(self, lookup, value, request=None):         from django.contrib.admin.filters import SimpleListFilter          model = self.model


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

# Either a local field filter, or no fields at all.             return True         valid_lookups = {self.date_hierarchy}        for filter_item in self.list_filter:        # RemovedInDjango60Warning: when the deprecation ends, replace with:        # for filter_item in self.get_list_filter(request):        list_filter = (            self.get_list_filter(request) if request is not None else self.list_filter        )        for filter_item in list_filter:             if isinstance(filter_item, type) and issubclass(                 filter_item, SimpleListFilter             ):diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py-- a/django/contrib/admin/views/main.py++ b/django/contrib/admin/views/main.py


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

<ins>import warnings</ins> from datetime import datetime, timedelta  from django import forms


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

from django.db.models import Exists, F, Field, ManyToOneRel, OrderBy, OuterRef from django.db.models.expressions import Combinable from django.urls import reversefrom django.utils.deprecation import RemovedInDjango60Warning from django.utils.http import urlencodefrom django.utils.inspect import func_supports_parameter from django.utils.timezone import make_aware from django.utils.translation import gettext


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

may_have_duplicates = False         has_active_filters = False         supports_request = func_supports_parameter(            self.model_admin.lookup_allowed, "request"        )        if not supports_request:            warnings.warn(                f"`request` must be added to the signature of "                f"{self.model_admin.__class__.__qualname__}.lookup_allowed().",                RemovedInDjango60Warning,            )         for key, value_list in lookup_params.items():             for value in value_list:                if not self.model_admin.lookup_allowed(key, value):                params = (key, value, request) if supports_request else (key, value)                if not self.model_admin.lookup_allowed(*params):                     raise DisallowedModelAdminLookup(f"Filtering by {key} not allowed")          filter_specs = []diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py-- a/django/contrib/auth/admin.py++ b/django/contrib/auth/admin.py


Question: lookupallowed fails to consider dynamic listfilter Description Currently, lookupallowed iterates over self.listfilter to determine valid params. This is technically incorrect since the introduction of getlistfilter() on ModelAdmin in 1.5, because it is possible to define a ModelAdmin such that self.listfilter is () but getlistfilter yields SimpleListFilter classes. To correct it, the above code would need to change from: for filteritem in self.listfilter: to for filteritem in self.getlistfilter(request): The problem is that now lookupallowed needs to accept request so that it can pass it back to getlistfilter In Django itself, that's actually reasonably acceptable as a change, because it's used infrequently - the only place it's actually used is in ChangeList.getfilters, which has access to the request. However, it is overridden in the wild without accept args, *kwargs, so it'd not be easy to provide a clean upgrade path.

),         ] + super().get_urls()     def lookup_allowed(self, lookup, value):    # RemovedInDjango60Warning: when the deprecation ends, replace with:    # def lookup_allowed(self, lookup, value, request):    def lookup_allowed(self, lookup, value, request=None):         # Don't allow lookups involving passwords.         return not lookup.startswith("password") and super().lookup_allowed(            lookup, value            lookup, value, request         )      @sensitive_post_parameters_m


Question: ImageField unnecessarily adds a postinit signal handler to the model Description While debugging some performance issues in a Django app, I found a codepath where most of the time was being spent on initializing Django models after fetching from the DB. It turns out that 30% of the time was being spent on evaluating postinit signals because we were using ImageField. However, the postinit signal handler is a noop because we don't use the widthfield / heightfield. If widthfield and heightfield are not set, removing the postinit signal should have no effect since the signal handler will return right away. Removing this signal handler gave us a 30-40% speedup on initializing models where ImageField was used.

# after their corresponding image field don't stay cleared by         # Model.__init__, see bug #11196.         # Only run post-initialization dimension update on non-abstract models        if not cls._meta.abstract:        # with width_field/height_field.        if not cls._meta.abstract and (self.width_field or self.height_field):             signals.post_init.connect(self.update_dimension_fields, sender=cls)      def update_dimension_fields(self, instance, force=False, *args, **kwargs):


Question: ImageField unnecessarily adds a postinit signal handler to the model Description While debugging some performance issues in a Django app, I found a codepath where most of the time was being spent on initializing Django models after fetching from the DB. It turns out that 30% of the time was being spent on evaluating postinit signals because we were using ImageField. However, the postinit signal handler is a noop because we don't use the widthfield / heightfield. If widthfield and heightfield are not set, removing the postinit signal should have no effect since the signal handler will return right away. Removing this signal handler gave us a 30-40% speedup on initializing models where ImageField was used.

Dimensions can be forced to update with force=True, which is how         ImageFileDescriptor.__set__ calls this method.         """        # Nothing to update if the field doesn't have dimension fields or if        # the field is deferred.        has_dimension_fields = self.width_field or self.height_field        if not has_dimension_fields or self.attname not in instance.__dict__:        # Nothing to update if the field is deferred.        if self.attname not in instance.__dict__:             return          # getattr will call the ImageFileDescriptor's __get__ method, which


Question: "random" template filter crashes on an empty list. Description first/last filters applied to a empty list do not raise anything and just returns a empty page. Example: {{ listvar|last }} Rendered with: def index(request): return render(request, '', context={"listvar": []}) Will result in empty page: [26/Apr/2023 09:15:49] "GET / HTTP/1.1" 200 0 As I undestand, 0 means no any characters in response content. The similar situation is with the first tag: {{ listvar|first }} While the random tag raises the IndexError and causes the server to response 500. Code snippet: {{ listvar|random }} In console we have: Internal Server Error: / Traceback (most recent call last): File "", line 47, in inner response = getresponse(request) File "", line 181, in getresponse response = wrappedcallback(request, callbackargs, callbackkwargs) File "/home/alex/Документы/django-", line 8, in index return render(request, '', context={"listvar": []}) File "", line 19, in render content = loader.rendertostring(templatename, context, request, using=using) File "", line 62, in rendertostring return (context, request) File "", line 61, in render return (context) File "", line 176, in render return (context) File "", line 168, in render return (context) File "", line 977, in render return SafeString(''.join([ File "", line 978, in <listcompnode.renderannotated(context) for node in self File "", line 938, in renderannotated return (context) File "", line 1038, in render output = self.filterexpression.resolve(context) File "", line 728, in resolve newobj = func(obj, argvals) File "", line 616, in random return (value) File "", line 347, in choice return seq[self._randbelow(len(seq))] IndexError: list index out of range [26/Apr/2023 09:30:03] "GET / HTTP/1.1" 500 Django version 4.0.1, python version Python 3.9.2 Expected behavior: Since all first, last and random tags returns an element from the list, their conduct in the case when the list is empty must be the same: either all 3 of them should raise an error or all 3 should return empty content.

@register.filter(is_safe=True) def random(value):     """Return a random item from the list."""    return random_module.choice(value)    try:        return random_module.choice(value)    except IndexError:        return ""   @register.filter("slice", is_safe=True)


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

response_redirect_class = HttpResponseRedirect     def get_fallback_language(self, request):        """        Return the fallback language for the current request based on the        settings. If LANGUAGE_CODE is a variant not included in the supported        languages, get_fallback_language() will try to fallback to a supported        generic variant.        Can be overridden to have a fallback language depending on the request,        e.g. based on top level domain.        """        try:            return translation.get_supported_language_variant(settings.LANGUAGE_CODE)        except LookupError:            return settings.LANGUAGE_CODE     def process_request(self, request):         urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)        i18n_patterns_used, _ = is_language_prefix_patterns_used(urlconf)        (            i18n_patterns_used,            prefixed_default_language,        ) = is_language_prefix_patterns_used(urlconf)         language = translation.get_language_from_request(             request, check_path=i18n_patterns_used         )        if not language:            language = self.get_fallback_language(request)        language_from_path = translation.get_language_from_path(request.path_info)        if (            not language_from_path            and i18n_patterns_used            and not prefixed_default_language        ):            language = settings.LANGUAGE_CODE         translation.activate(language)         request.LANGUAGE_CODE = translation.get_language()      def process_response(self, request, response):         language = translation.get_language()         language_from_path = translation.get_language_from_path(request.path_info)        language_from_request = translation.get_language_from_request(request)         urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)         (             i18n_patterns_used,


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

response.status_code == 404             and not language_from_path             and i18n_patterns_used            and (prefixed_default_language or language_from_request)            and prefixed_default_language         ):             # Maybe the language code is missing in the URL? Try adding the             # language prefix and redirecting to that URL.diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py-- a/django/urls/resolvers.py++ b/django/urls/resolvers.py


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

from django.utils.functional import cached_property from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes from django.utils.regex_helper import _lazy_re_compile, normalizefrom django.utils.translation import get_language, get_supported_language_variantfrom django.utils.translation import get_language  from .converters import get_converter from .exceptions import NoReverseMatch, Resolver404


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

@property     def language_prefix(self):         language_code = get_language() or settings.LANGUAGE_CODE        default_language = get_supported_language_variant(settings.LANGUAGE_CODE)        if language_code == default_language and not self.prefix_default_language:        if language_code == settings.LANGUAGE_CODE and not self.prefix_default_language:             return ""         else:             return "%s/" % language_codediff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py-- a/django/utils/translation/__init__.py++ b/django/utils/translation/__init__.py


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

"get_language_from_request",     "get_language_info",     "get_language_bidi",    "get_supported_language_variant",     "check_for_language",     "to_language",     "to_locale",diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py-- a/django/utils/translation/trans_null.py++ b/django/utils/translation/trans_null.py


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

def get_language_from_request(request, check_path=False):    return None    return settings.LANGUAGE_CODE   def get_language_from_path(request):diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py-- a/django/utils/translation/trans_real.py++ b/django/utils/translation/trans_real.py


Question: Translatable URL patterns raise 404 for non-English default language when prefixdefaultlanguage=False is used. Description A simple django project with instruction to replicate the bug can be found here: github repo In brief: prefixdefaultlanguage = False raises HTTP 404 for the default unprefixed pages if LANGUAGECODE is not "en". I think the problem is that the function getlanguagefrompath in returns None in case of failure instead of LANGUAGECODE: diff in 4.2 Consequently, other mechanisms are used to get the language (cookies or headers) that do not work neither. Related issue with my last comment adding some extra context: It is the first time I contribute to django, I hope the bug report is OK. I am also willing to write the patch and test if required.

return get_supported_language_variant(accept_lang)         except LookupError:             continue    return None    try:        return get_supported_language_variant(settings.LANGUAGE_CODE)    except LookupError:        return settings.LANGUAGE_CODE   @functools.lru_cache(maxsize=1000)


Question: Error E108 does not cover some cases Description (last modified by Baha Sdtbekov) I have two models, Question and Choice. And if I write listdisplay = ["choice"] in QuestionAdmin, I get no errors. But when I visit /admin/polls/question/, the following trace is returned: Internal Server Error: /admin/polls/question/ Traceback (most recent call last): File "", line 334, in labelforfield field = getnongfkfield(, name) File "", line 310, in getnongfkfield raise FieldDoesNotExist() During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 55, in inner response = getresponse(request) File "", line 220, in getresponse response = () File "", line 111, in render self.content = self.renderedcontent File "", line 89, in renderedcontent return (context, self.request) File "", line 61, in render return (context) File "", line 175, in render return (context) File "", line 167, in render return (context) File "", line 1005, in render return SafeString("".join([node.renderannotated(context) for node in self])) File "", line 1005, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) File "", line 966, in renderannotated return (context) File "", line 157, in render return (context) File "", line 167, in render return (context) File "", line 1005, in render return SafeString("".join([node.renderannotated(context) for node in self])) File "", line 1005, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) File "", line 966, in renderannotated return (context) File "", line 157, in render return (context) File "", line 167, in render return (context) File "", line 1005, in render return SafeString("".join([node.renderannotated(context) for node in self])) File "", line 1005, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) File "", line 966, in renderannotated return (context) File "", line 63, in render result = (context) File "", line 1005, in render return SafeString("".join([node.renderannotated(context) for node in self])) File "", line 1005, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) File "", line 966, in renderannotated return (context) File "", line 63, in render result = (context) File "", line 1005, in render return SafeString("".join([node.renderannotated(context) for node in self])) File "", line 1005, in <listcompreturn SafeString("".join([node.renderannotated(context) for node in self])) File "", line 966, in renderannotated return (context) File "", line 45, in render return super().render(context) File "", line 258, in render dict = (resolvedargs, *resolvedkwargs) File "", line 326, in resultlist headers = list(resultheaders(cl)) File "", line 90, in resultheaders text, attr = labelforfield( File "", line 362, in labelfor_field raise AttributeError(message) AttributeError: Unable to lookup 'choice' on Question or QuestionAdmin [24/Apr/2023 15:43:32] "GET /admin/polls/question/ HTTP/1.1" 500 I suggest that error E108 be updated to cover this case as well For reproduce see github

id="admin.E108",                     )                 ]        if isinstance(field, models.ManyToManyField) or (            getattr(field, "rel", None) and field.rel.field.many_to_one        ):        if (            getattr(field, "is_relation", False)            and (field.many_to_many or field.one_to_many)        ) or (getattr(field, "rel", None) and field.rel.field.many_to_one):             return [                 checks.Error(                     f"The value of '{label}' must not be a many-to-many field or a "


Question: Reduce Add/RemoveIndex migration operations. Description We should reduce AddIndex/RemoveIndex operations when optimizing migration operations.

def migration_name_fragment(self):         return "%s_%s" % (self.model_name_lower, self.index.name.lower()) <ins>    def reduce(self, operation, app_label):        if isinstance(operation, RemoveIndex) and self.index.name == operation.name:            return []        return super().reduce(operation, app_label)</ins>  class RemoveIndex(IndexOperation):     """Remove an index from a model."""


Question: Squashing migrations with Meta.indextogether -indexes transition should remove deprecation warnings. Description Squashing migrations with Meta.indextogether -Meta.indexes transition should remove deprecation warnings. As far as I'm aware, it's a 4.2 release blocker because you cannot get rid of the index_together deprecation warnings without rewriting migrations, see comment.

managers=self.managers,                     ),                 ]<ins>        elif (            isinstance(operation, IndexOperation)            and self.name_lower == operation.model_name_lower        ):            if isinstance(operation, AddIndex):                return [                    CreateModel(                        self.name,                        fields=self.fields,                        options={                            **self.options,                            "indexes": [                                *self.options.get("indexes", []),                                operation.index,                            ],                        },                        bases=self.bases,                        managers=self.managers,                    ),                ]            elif isinstance(operation, RemoveIndex):                options_indexes = [                    index                    for index in self.options.get("indexes", [])                    if index.name != operation.name                ]                return [                    CreateModel(                        self.name,                        fields=self.fields,                        options={                            **self.options,                            "indexes": options_indexes,                        },                        bases=self.bases,                        managers=self.managers,                    ),                ]            elif isinstance(operation, RenameIndex) and operation.old_fields:                options_index_together = {                    fields                    for fields in self.options.get("index_together", [])                    if fields != operation.old_fields                }                if options_index_together:                    self.options["index_together"] = options_index_together                else:                    self.options.pop("index_together", None)                return [                    CreateModel(                        self.name,                        fields=self.fields,                        options={                            **self.options,                            "indexes": [                                *self.options.get("indexes", []),                                models.Index(                                    fields=operation.old_fields, name=operation.new_name                                ),                            ],                        },                        bases=self.bases,                        managers=self.managers,                    ),                ]</ins>         return super().reduce(operation, app_label)


Question: dbshell management command can crash if DATABASES["name"] is a PosixPath Description With a sqlite database configured in like this: DATABASES = { "default": { "ENGINE": "", "NAME": BASEDIR / "db.sqlite3", } } exiting dbshell using Control - d sometimes results in this exception: Traceback (most recent call last): File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 30, in handle (options["parameters"]) File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 28, in runshell (args, env=env, check=True) File "", line 571, in run raise CalledProcessError(retcode, , subprocess.CalledProcessError: Command '['sqlite3', PosixPath('/home/ubuntu/planning-poker/db.sqlite3')]' returned non-zero exit status 1. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/ubuntu/planning-", line 30, in <modulemain() File "/home/ubuntu/planning-", line 26, in main executefromcommandline() File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 442, in executefromcommandline utility.execute() File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 436, in execute self.fetchcommand(subcommand).runfromargv() File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 412, in runfromargv self.execute(args, cmd_options) File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 458, in execute output = (args, options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/virtualenv/lib/python3.11/site-", line 44, in handle " ".join(e.cmd), ^^^^^^^^^^^^^^^ TypeError: sequence item 1: expected str instance, PosixPath found coercing each item in e.cmd to string should fix this.

raise CommandError(                 '"%s" returned non-zero exit status %s.'                 % (                    " ".join(e.cmd),                    " ".join(map(str, e.cmd)),                     e.returncode,                 ),                 returncode=e.returncode,


Question: forceinsert flag is not passed when saving parents on inherited models. Description We're using non-abstract model inheritance (table per model class) and issuing our own primary keys. When saving we pass forceinsert=True to prevent the extra UPDATE statement that precedes the INSERT. The forceinsert flag is respected on the child table but not on the parent. So given: class ParentModel(models.Model): id = models.BigIntegerField(primarykey=True) class ChildModel(ParentModel): pass ChildModel(id=1).save(forceinsert=True) We'll see queries: UPDATE appparentmodel (no rows affected) INSERT appparentmodel INSERT appchildmodel This is because Model.savebase doesn't pass forceinsert along to Model.saveparents, and onto Model.savetable. Doing so would prevent the extra UPDATE and respect the spirit of the forceinsert feature. This is a change I've made locally and seems to work / is pretty straightforward. I'm curious though if there's intent behind not carrying the forceinsert functionality through for parents. I couldn't find any discussion on the topic. For context about why this is particularly problematic in our case -- we're using MySQL w/ Innodb and Innodb will take out different exclusive locks for the UPDATE and INSERT in question -- so if you're creating new ChildModel instances in parallel you can get deadlocks when multiple threads issue query and then need a lock with insert intention in order to get .

asave.alters_data = True <ins>    @classmethod    def _validate_force_insert(cls, force_insert):        if force_insert is False:            return ()        if force_insert is True:            return (cls,)        if not isinstance(force_insert, tuple):            raise TypeError("force_insert must be a bool or tuple.")        for member in force_insert:            if not isinstance(member, ModelBase):                raise TypeError(                    f"Invalid force_insert member. {member!r} must be a model subclass."                )            if not issubclass(cls, member):                raise TypeError(                    f"Invalid force_insert member. {member.__qualname__} must be a "                    f"base of {cls.__qualname__}."                )        return force_insert</ins>     def save_base(         self,         raw=False,


Question: forceinsert flag is not passed when saving parents on inherited models. Description We're using non-abstract model inheritance (table per model class) and issuing our own primary keys. When saving we pass forceinsert=True to prevent the extra UPDATE statement that precedes the INSERT. The forceinsert flag is respected on the child table but not on the parent. So given: class ParentModel(models.Model): id = models.BigIntegerField(primarykey=True) class ChildModel(ParentModel): pass ChildModel(id=1).save(forceinsert=True) We'll see queries: UPDATE appparentmodel (no rows affected) INSERT appparentmodel INSERT appchildmodel This is because Model.savebase doesn't pass forceinsert along to Model.saveparents, and onto Model.savetable. Doing so would prevent the extra UPDATE and respect the spirit of the forceinsert feature. This is a change I've made locally and seems to work / is pretty straightforward. I'm curious though if there's intent behind not carrying the forceinsert functionality through for parents. I couldn't find any discussion on the topic. For context about why this is particularly problematic in our case -- we're using MySQL w/ Innodb and Innodb will take out different exclusive locks for the UPDATE and INSERT in question -- so if you're creating new ChildModel instances in parallel you can get deadlocks when multiple threads issue query and then need a lock with insert intention in order to get .

with context_manager:             parent_inserted = False             if not raw:                parent_inserted = self._save_parents(cls, using, update_fields)                # Validate force insert only when parents are inserted.                force_insert = self._validate_force_insert(force_insert)                parent_inserted = self._save_parents(                    cls, using, update_fields, force_insert                )             updated = self._save_table(                 raw,                 cls,


Question: forceinsert flag is not passed when saving parents on inherited models. Description We're using non-abstract model inheritance (table per model class) and issuing our own primary keys. When saving we pass forceinsert=True to prevent the extra UPDATE statement that precedes the INSERT. The forceinsert flag is respected on the child table but not on the parent. So given: class ParentModel(models.Model): id = models.BigIntegerField(primarykey=True) class ChildModel(ParentModel): pass ChildModel(id=1).save(forceinsert=True) We'll see queries: UPDATE appparentmodel (no rows affected) INSERT appparentmodel INSERT appchildmodel This is because Model.savebase doesn't pass forceinsert along to Model.saveparents, and onto Model.savetable. Doing so would prevent the extra UPDATE and respect the spirit of the forceinsert feature. This is a change I've made locally and seems to work / is pretty straightforward. I'm curious though if there's intent behind not carrying the forceinsert functionality through for parents. I couldn't find any discussion on the topic. For context about why this is particularly problematic in our case -- we're using MySQL w/ Innodb and Innodb will take out different exclusive locks for the UPDATE and INSERT in question -- so if you're creating new ChildModel instances in parallel you can get deadlocks when multiple threads issue query and then need a lock with insert intention in order to get .

save_base.alters_data = True     def _save_parents(self, cls, using, update_fields, updated_parents=None):    def _save_parents(        self, cls, using, update_fields, force_insert, updated_parents=None    ):         """Save all the parents of cls using values from self."""         meta = cls._meta         inserted = False


Question: forceinsert flag is not passed when saving parents on inherited models. Description We're using non-abstract model inheritance (table per model class) and issuing our own primary keys. When saving we pass forceinsert=True to prevent the extra UPDATE statement that precedes the INSERT. The forceinsert flag is respected on the child table but not on the parent. So given: class ParentModel(models.Model): id = models.BigIntegerField(primarykey=True) class ChildModel(ParentModel): pass ChildModel(id=1).save(forceinsert=True) We'll see queries: UPDATE appparentmodel (no rows affected) INSERT appparentmodel INSERT appchildmodel This is because Model.savebase doesn't pass forceinsert along to Model.saveparents, and onto Model.savetable. Doing so would prevent the extra UPDATE and respect the spirit of the forceinsert feature. This is a change I've made locally and seems to work / is pretty straightforward. I'm curious though if there's intent behind not carrying the forceinsert functionality through for parents. I couldn't find any discussion on the topic. For context about why this is particularly problematic in our case -- we're using MySQL w/ Innodb and Innodb will take out different exclusive locks for the UPDATE and INSERT in question -- so if you're creating new ChildModel instances in parallel you can get deadlocks when multiple threads issue query and then need a lock with insert intention in order to get .

cls=parent,                     using=using,                     update_fields=update_fields,                    force_insert=force_insert,                     updated_parents=updated_parents,                 )                 updated = self._save_table(                     cls=parent,                     using=using,                     update_fields=update_fields,                    force_insert=parent_inserted,                    force_insert=parent_inserted or issubclass(parent, force_insert),                 )                 if not updated:                     inserted = True


Question: no longer called for JSONField Description (last modified by Julie Rymer) Hello, I just upgraded from django 4.1 to 4.2 and I have a custom JSONField with a getprepvalue() override that stopped working. After searching a bit, I saw that was because JSONField.getprepvalue() is no longer called in 4.2 (). I think this issue need a resolution either: JSONField should call getprepvalue() like all other fields type, because this is the method that the documentation tell us to override in custom fields. Otherwise we need to override getdbprepvalue() which is heavier and does not have the same purpose. I think simply replacing (value, self.encoder) with (self.getprepvalue(value), self.encoder) in JSONField.getdbprepvalue() would fix this If there is a good reason to no longer call getprepvalue(), this exception for JSONField should be clearly documented in custom getprepvalue() doc. It should also be to Backwards incompatible changes in 4.2 release note because I got stuck with this issue with no warning when migrating. PS: seems to be related but in fact is about Django 3.2 so it is not the current issue

return "JSONField"      def get_db_prep_value(self, value, connection, prepared=False):<ins>        if not prepared:            value = self.get_prep_value(value)</ins>         # RemovedInDjango51Warning: When the deprecation ends, replace with:         # if (         #     isinstance(value, expressions.Value)


Question: makemigrations --update should respect the --name option. Description (last modified by David Sanders) This may be intentional behaviour but the docs don't mention this so creating a ticket to update docs or correct behaviour: If you create a migration with a custom name: $ makemigrations --name foo Migrations for 'updaterename': Create model Foo then running --update will change the name "foo" to the autogenerated one based on the operations: $ makemigrations --update Migrations for 'updaterename': Create model Foo Deleted My opinion is that it shouldn't as it violates the principle of least astonishment even though the --name argument wasn't supplied. EDIT: This is my first time using --update and here are a few other observations which could indicate that it requires broader discussion: It doesn't utilise the --name argument so it's impossible to customise the name during --update It'd be nice to provide --no-optimize option to --update, here's my use-case: 3-step non-null field addition. After doing nullable step 1, elidable data migration step 2, I want to merge the step 3 non-null update into the migration but --update optimizes this into a single step. Perhaps --update requires a rethink?

)             # Update name.             previous_migration_path = MigrationWriter(leaf_migration).path            suggested_name = (                leaf_migration.name[:4] + "_" + leaf_migration.suggest_name()            )            name_fragment = self.migration_name or leaf_migration.suggest_name()            suggested_name = leaf_migration.name[:4] + f"_{name_fragment}"             if leaf_migration.name == suggested_name:                 new_name = leaf_migration.name + "_updated"             else:


Question: Template filter should not escape the joining string if is Description Consider the following template code snippet: {% autoescape off %} {{ somelist|join:somevar }} {% endautoescape %} in this case, the items inside somelist will not be escaped (matching the expected behavior) but somevar will forcibly be escaped. From the docs for autoescape or join I don't think this is expected behavior. The following testcase illustrates what I think is a bug in the join filter (run inside the templatetests/filtertests folder): from django.template.defaultfilters import escape from import SimpleTestCase from ..utils import setup class RegressionTests(SimpleTestCase): '{{ somelist|join:somevar }}'}) def testjoin01(self): somelist = ["<pHello World!</p", "beta & me", "beta & me

"""Join a list with a string, like Python's ``str.join(list)``."""     try:         if autoescape:            value = [conditional_escape(v) for v in value]        data = conditional_escape(arg).join(value)            data = conditional_escape(arg).join([conditional_escape(v) for v in value])        else:            data = arg.join(value)     except TypeError:  # Fail silently if arg isn't iterable.         return value     return mark_safe(data)


Question: New template filter Description Following , and after some conversations within the security team, it seems appropriate to provide a new template filter escapeseq which would be to escape what safeseq is to safe. An example of usage would be: {{ somelistjoin:"," }} where each item of somelist is escaped before applying the join operation. This usage makes sense in a context where autoescape is off.

return conditional_escape(value)  <ins>@register.filter(is_safe=True)def escapeseq(value):    """    An "escape" filter for sequences. Mark each element in the sequence,    individually, as a string that should be auto-escaped. Return a list with    the results.    """    return [conditional_escape(obj) for obj in value]</ins> @register.filter(is_safe=True) @stringfilter def force_escape(value):


Question: Case-When aggregation over aggregated fields doesn't work since 4.2 Description (last modified by Denis Roldán) This same QuerySet was working on 4.1.X and prior versions and stopped working on 4.2.X: annotatedusers = usersqs.annotate( totalthings=Subquery( (userid=OuterRef("pk")).annotate( totalobjs=F("total") ).values("totalobjs") ) ) annotatedusers.aggregate( sumtotalobjs=Sum("totalthings"), avgconversionrate=Case( When( sumtotalobjs=0, then=0, ), default=Round( (Sum("sumtotalconfirmedobjs") / Sum("sumtotalobjs")) 100, 2 ), outputfield=FloatField(), ) ) As you can see sumtotalobjs is an aggregated field that is also used on a second field to calculate the conversion rate. To avoid a zero division problem, we were using a Case-When clause over that field. It works well on any 4.1 and prior versions but stopped working since 4.2, raising a FieldError like: Cannot resolve keyword 'sumtotalobjs' into field The bug is reproducible with an extra test on the django aggregation test suite: def testreferencedgroupbyaggregationoverannotation(self): totalbooksqs = ( (authorspk=OuterRef("pk")) .orderby() .values("pk") .annotate(total=Count("pk")) .values("total") ) annotatedauthors = Author.objects.annotate( totalbooks=Subquery(totalbooksqs.annotate( totalbooks=F("total") ).values("totalbooks")), totalbooksa=Subquery(( nameistartswith="a" ).annotate( totalbooksa=F("total") ).values("totalbooksa")), ).values( "pk", "totalbooks", "totalbooksa", ).orderby("-totalbooks") totals = annotatedauthors.aggregate( sumtotalbooks=Sum("totalbooks"), sumtotalbooksa=Sum("totalbooksa"), aovertotalrate=Case( When( sumtotalbooks=0, then=0, ), default=Round( (Sum("totalbooksa") / Sum("totalbooks")) 100, 2 ), outputfield=FloatField(), ), ) self.assertEqual(totals['sumtotalbooks'], 3) self.assertEqual(totals['sumtotalbooksa'], 0) self.assertEqual(totals['aovertotalrate'], 0) Thanks for the support!

c.filter = c.filter and c.filter.resolve_expression(             query, allow_joins, reuse, summarize         )        if not summarize:        if summarize:            # Summarized aggregates cannot refer to summarized aggregates.            for ref in c.get_refs():                if query.annotations[ref].is_summary:                    raise FieldError(                        f"Cannot compute {c.name}('{ref}'): '{ref}' is an aggregate"                    )        elif not self.is_summary:             # Call Aggregate.get_source_expressions() to avoid             # returning self.filter and including that in this loop.             expressions = super(Aggregate, c).get_source_expressions()diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py-- a/django/db/models/expressions.py++ b/django/db/models/expressions.py


Question: Case-When aggregation over aggregated fields doesn't work since 4.2 Description (last modified by Denis Roldán) This same QuerySet was working on 4.1.X and prior versions and stopped working on 4.2.X: annotatedusers = usersqs.annotate( totalthings=Subquery( (userid=OuterRef("pk")).annotate( totalobjs=F("total") ).values("totalobjs") ) ) annotatedusers.aggregate( sumtotalobjs=Sum("totalthings"), avgconversionrate=Case( When( sumtotalobjs=0, then=0, ), default=Round( (Sum("sumtotalconfirmedobjs") / Sum("sumtotalobjs")) 100, 2 ), outputfield=FloatField(), ) ) As you can see sumtotalobjs is an aggregated field that is also used on a second field to calculate the conversion rate. To avoid a zero division problem, we were using a Case-When clause over that field. It works well on any 4.1 and prior versions but stopped working since 4.2, raising a FieldError like: Cannot resolve keyword 'sumtotalobjs' into field The bug is reproducible with an extra test on the django aggregation test suite: def testreferencedgroupbyaggregationoverannotation(self): totalbooksqs = ( (authorspk=OuterRef("pk")) .orderby() .values("pk") .annotate(total=Count("pk")) .values("total") ) annotatedauthors = Author.objects.annotate( totalbooks=Subquery(totalbooksqs.annotate( totalbooks=F("total") ).values("totalbooks")), totalbooksa=Subquery(( nameistartswith="a" ).annotate( totalbooksa=F("total") ).values("totalbooksa")), ).values( "pk", "totalbooks", "totalbooksa", ).orderby("-totalbooks") totals = annotatedauthors.aggregate( sumtotalbooks=Sum("totalbooks"), sumtotalbooksa=Sum("totalbooksa"), aovertotalrate=Case( When( sumtotalbooks=0, then=0, ), default=Round( (Sum("totalbooksa") / Sum("totalbooks")) 100, 2 ), outputfield=FloatField(), ), ) self.assertEqual(totals['sumtotalbooks'], 3) self.assertEqual(totals['sumtotalbooksa'], 0) self.assertEqual(totals['aovertotalrate'], 0) Thanks for the support!

template = "(%(subquery)s)"     contains_aggregate = False     empty_result_set_value = None    subquery = True      def __init__(self, queryset, output_field=None, **extra):         # Allow the usage of both QuerySet and sql.Query objects.diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py-- a/django/db/models/sql/query.py++ b/django/db/models/sql/query.py