-
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py
a
|
b
|
class FieldListFilter(ListFilter):
|
152 | 152 | @classmethod |
153 | 153 | def create(cls, field, request, params, model, model_admin, field_path): |
154 | 154 | for test, list_filter_class in cls._field_list_filters: |
155 | | if not test(field): |
156 | | continue |
157 | | return list_filter_class(field, request, params, model, model_admin, field_path=field_path) |
| 155 | if test(field): |
| 156 | return list_filter_class(field, request, params, model, model_admin, field_path=field_path) |
158 | 157 | |
159 | 158 | |
160 | 159 | class RelatedFieldListFilter(FieldListFilter): |
-
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
a
|
b
|
class InlineFieldset(Fieldset):
|
367 | 367 | def __iter__(self): |
368 | 368 | fk = getattr(self.formset, "fk", None) |
369 | 369 | for field in self.fields: |
370 | | if fk and fk.name == field: |
371 | | continue |
372 | | yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin) |
| 370 | if not fk or fk.name != field: |
| 371 | yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin) |
373 | 372 | |
374 | 373 | |
375 | 374 | class AdminErrorList(forms.utils.ErrorList): |
-
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
a
|
b
|
class ModelAdmin(BaseModelAdmin):
|
831 | 831 | # Then gather them from the model admin and all parent classes, |
832 | 832 | # starting with self and working back up. |
833 | 833 | for klass in self.__class__.mro()[::-1]: |
834 | | class_actions = getattr(klass, 'actions', []) |
835 | | # Avoid trying to iterate over None |
836 | | if not class_actions: |
837 | | continue |
| 834 | class_actions = getattr(klass, 'actions', []) or [] |
838 | 835 | actions.extend(self.get_action(action) for action in class_actions) |
839 | 836 | |
840 | 837 | # get_action might have returned None, so filter any of those out. |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
1498 | 1495 | ModelForm = self.get_form(request, obj) |
1499 | 1496 | if request.method == 'POST': |
1500 | 1497 | form = ModelForm(request.POST, request.FILES, instance=obj) |
1501 | | if form.is_valid(): |
1502 | | form_validated = True |
| 1498 | form_validated = form.is_valid() |
| 1499 | if form_validated: |
1503 | 1500 | new_object = self.save_form(request, form, change=not add) |
1504 | 1501 | else: |
1505 | | form_validated = False |
1506 | 1502 | new_object = form.instance |
1507 | 1503 | formsets, inline_instances = self._create_formsets(request, new_object, change=not add) |
1508 | 1504 | if all_valid(formsets) and form_validated: |
-
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
a
|
b
|
def result_headers(cl):
|
128 | 128 | order_type = '' |
129 | 129 | new_order_type = 'asc' |
130 | 130 | sort_priority = 0 |
131 | | sorted = False |
| 131 | sorted = i in ordering_field_columns |
132 | 132 | # Is it currently being sorted on? |
133 | | if i in ordering_field_columns: |
134 | | sorted = True |
| 133 | if sorted: |
135 | 134 | order_type = ordering_field_columns.get(i).lower() |
136 | 135 | sort_priority = list(ordering_field_columns).index(i) + 1 |
137 | 136 | th_classes.append('sorted %sending' % order_type) |
-
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
a
|
b
|
def prepare_lookup_value(key, value):
|
53 | 53 | if key.endswith('__in'): |
54 | 54 | value = value.split(',') |
55 | 55 | # if key ends with __isnull, special case '' and the string literals 'false' and '0' |
56 | | if key.endswith('__isnull'): |
57 | | if value.lower() in ('', 'false', '0'): |
58 | | value = False |
59 | | else: |
60 | | value = True |
| 56 | elif key.endswith('__isnull'): |
| 57 | value = value.lower() not in ('', 'false', '0') |
61 | 58 | return value |
62 | 59 | |
63 | 60 | |
-
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
a
|
b
|
class ChangeList:
|
378 | 378 | else: |
379 | 379 | if isinstance(field.remote_field, models.ManyToOneRel): |
380 | 380 | # <FK>_id field names don't require a join. |
381 | | if field_name == field.get_attname(): |
382 | | continue |
383 | | return True |
| 381 | if field_name != field.get_attname(): |
| 382 | return True |
384 | 383 | return False |
385 | 384 | |
386 | 385 | def url_for_result(self, result): |
-
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
a
|
b
|
class AutocompleteMixin:
|
438 | 438 | str(option_value) in value and |
439 | 439 | (has_selected is False or self.allow_multiple_selected) |
440 | 440 | ) |
441 | | if selected is True and has_selected is False: |
442 | | has_selected = True |
| 441 | has_selected |= selected |
443 | 442 | index = len(default[1]) |
444 | 443 | subgroup = default[1] |
445 | 444 | subgroup.append(self.create_option(name, option_value, option_label, selected_choices, index)) |
-
diff --git a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py
index 0a64a0e..e92c701 100644
a
|
b
|
class Command(BaseCommand):
|
41 | 41 | collector.collect([ct]) |
42 | 42 | |
43 | 43 | for obj_type, objs in collector.data.items(): |
44 | | if objs == {ct}: |
45 | | continue |
46 | | ct_info.append(' - %s %s object(s)' % ( |
47 | | len(objs), |
48 | | obj_type._meta.label, |
49 | | )) |
| 44 | if objs != {ct}: |
| 45 | ct_info.append(' - %s %s object(s)' % ( |
| 46 | len(objs), |
| 47 | obj_type._meta.label, |
| 48 | )) |
50 | 49 | content_type_display = '\n'.join(ct_info) |
51 | 50 | self.stdout.write("""Some content types in your database are stale and can be deleted. |
52 | 51 | Any objects that depend on these content types will also be deleted. |
-
diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py
a
|
b
|
class OGRGeometry(GDALBase):
|
142 | 142 | def _from_json(geom_input): |
143 | 143 | ptr = capi.from_json(geom_input) |
144 | 144 | if GDAL_VERSION < (2, 0): |
145 | | has_srs = True |
146 | 145 | try: |
147 | 146 | capi.get_geom_srs(ptr) |
148 | 147 | except SRSException: |
149 | | has_srs = False |
150 | | if not has_srs: |
151 | 148 | srs = SpatialReference(4326) |
152 | 149 | capi.assign_srs(ptr, srs.ptr) |
153 | 150 | return ptr |
-
diff --git a/django/contrib/gis/geos/linestring.py b/django/contrib/gis/geos/linestring.py
a
|
b
|
class LineString(LinearGeometryMixin, GEOSGeometry):
|
49 | 49 | ) |
50 | 50 | ) |
51 | 51 | |
52 | | if isinstance(coords, (tuple, list)): |
| 52 | numpy_coords = not isinstance(coords, (tuple, list)) |
| 53 | if numpy_coords: |
| 54 | shape = coords.shape # Using numpy's shape. |
| 55 | if len(shape) != 2: |
| 56 | raise TypeError('Too many dimensions.') |
| 57 | self._checkdim(shape[1]) |
| 58 | ndim = shape[1] |
| 59 | else: |
53 | 60 | # Getting the number of coords and the number of dimensions -- which |
54 | 61 | # must stay the same, e.g., no LineString((1, 2), (1, 2, 3)). |
55 | 62 | ndim = None |
… |
… |
class LineString(LinearGeometryMixin, GEOSGeometry):
|
63 | 70 | self._checkdim(ndim) |
64 | 71 | elif len(coord) != ndim: |
65 | 72 | raise TypeError('Dimension mismatch.') |
66 | | numpy_coords = False |
67 | | else: |
68 | | shape = coords.shape # Using numpy's shape. |
69 | | if len(shape) != 2: |
70 | | raise TypeError('Too many dimensions.') |
71 | | self._checkdim(shape[1]) |
72 | | ndim = shape[1] |
73 | | numpy_coords = True |
74 | 73 | |
75 | 74 | # Creating a coordinate sequence object because it is easier to |
76 | 75 | # set the points using its methods. |
-
diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py
a
|
b
|
class SessionStore(SessionBase):
|
61 | 61 | modification = os.stat(self._key_to_file()).st_mtime |
62 | 62 | if settings.USE_TZ: |
63 | 63 | modification = datetime.datetime.utcfromtimestamp(modification) |
64 | | modification = modification.replace(tzinfo=timezone.utc) |
65 | | else: |
66 | | modification = datetime.datetime.fromtimestamp(modification) |
67 | | return modification |
| 64 | return modification.replace(tzinfo=timezone.utc) |
| 65 | return datetime.datetime.fromtimestamp(modification) |
68 | 66 | |
69 | 67 | def _expiry_date(self, session_data): |
70 | 68 | """ |
-
diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py
a
|
b
|
class HashedFilesMixin:
|
86 | 86 | parsed_name = urlsplit(unquote(name)) |
87 | 87 | clean_name = parsed_name.path.strip() |
88 | 88 | filename = (filename and urlsplit(unquote(filename)).path.strip()) or clean_name |
89 | | opened = False |
90 | | if content is None: |
| 89 | opened = content is None |
| 90 | if opened: |
91 | 91 | if not self.exists(filename): |
92 | 92 | raise ValueError("The file '%s' could not be found with %r." % (filename, self)) |
93 | 93 | try: |
… |
… |
class HashedFilesMixin:
|
95 | 95 | except IOError: |
96 | 96 | # Handle directory paths and fragments |
97 | 97 | return name |
98 | | opened = True |
99 | 98 | try: |
100 | 99 | file_hash = self.file_hash(clean_name, content) |
101 | 100 | finally: |
-
diff --git a/django/core/checks/templates.py b/django/core/checks/templates.py
a
|
b
|
E002 = Error(
|
17 | 17 | |
18 | 18 | @register(Tags.templates) |
19 | 19 | def check_setting_app_dirs_loaders(app_configs, **kwargs): |
20 | | passed_check = True |
21 | | for conf in settings.TEMPLATES: |
22 | | if not conf.get('APP_DIRS'): |
23 | | continue |
24 | | if 'loaders' in conf.get('OPTIONS', {}): |
25 | | passed_check = False |
26 | | return [] if passed_check else [E001] |
| 20 | return [E001] if any(conf.get('APP_DIRS') and |
| 21 | 'loaders' in conf.get('OPTIONS', {}) for conf in settings.TEMPLATES) else [] |
27 | 22 | |
28 | 23 | |
29 | 24 | @register(Tags.templates) |
-
diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py
a
|
b
|
class MemoryFileUploadHandler(FileUploadHandler):
|
160 | 160 | """ |
161 | 161 | # Check the content-length header to see if we should |
162 | 162 | # If the post is too large, we cannot use the Memory handler. |
163 | | if content_length > settings.FILE_UPLOAD_MAX_MEMORY_SIZE: |
164 | | self.activated = False |
165 | | else: |
166 | | self.activated = True |
| 163 | self.activated = content_length <= settings.FILE_UPLOAD_MAX_MEMORY_SIZE |
167 | 164 | |
168 | 165 | def new_file(self, *args, **kwargs): |
169 | 166 | super().new_file(*args, **kwargs) |
-
diff --git a/django/core/mail/message.py b/django/core/mail/message.py
a
|
b
|
class EmailMessage:
|
271 | 271 | # Use cached DNS_NAME for performance |
272 | 272 | msg['Message-ID'] = make_msgid(domain=DNS_NAME) |
273 | 273 | for name, value in self.extra_headers.items(): |
274 | | if name.lower() == 'from': # From is already handled |
275 | | continue |
276 | | msg[name] = value |
| 274 | if name.lower() != 'from': # From is already handled |
| 275 | msg[name] = value |
277 | 276 | return msg |
278 | 277 | |
279 | 278 | def recipients(self): |
-
diff --git a/django/core/signing.py b/django/core/signing.py
a
|
b
|
def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma
|
132 | 132 | # TimestampSigner.unsign() returns str but base64 and zlib compression |
133 | 133 | # operate on bytes. |
134 | 134 | base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age)) |
135 | | decompress = False |
136 | | if base64d[:1] == b'.': |
| 135 | decompress = base64d[:1] == b'.' |
| 136 | if decompress: |
137 | 137 | # It's compressed; uncompress it first |
138 | 138 | base64d = base64d[1:] |
139 | | decompress = True |
140 | 139 | data = b64_decode(base64d) |
141 | 140 | if decompress: |
142 | 141 | data = zlib.decompress(data) |
-
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
a
|
b
|
class BaseDatabaseSchemaEditor:
|
570 | 570 | # db_index=True. |
571 | 571 | index_names = self._constraint_names(model, [old_field.column], index=True, type_=Index.suffix) |
572 | 572 | for index_name in index_names: |
573 | | if index_name in meta_index_names: |
| 573 | if index_name not in meta_index_names: |
574 | 574 | # The only way to check if an index was created with |
575 | 575 | # db_index=True or with Index(['field'], name='foo') |
576 | 576 | # is to look at its name (refs #28053). |
577 | | continue |
578 | | self.execute(self._delete_constraint_sql(self.sql_delete_index, model, index_name)) |
| 577 | self.execute(self._delete_constraint_sql(self.sql_delete_index, model, index_name)) |
579 | 578 | # Change check constraints? |
580 | 579 | if old_db_params['check'] != new_db_params['check'] and old_db_params['check']: |
581 | 580 | constraint_names = self._constraint_names(model, [old_field.column], check=True) |
-
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
a
|
b
|
class MigrationAutodetector:
|
261 | 261 | deps_satisfied = True |
262 | 262 | operation_dependencies = set() |
263 | 263 | for dep in operation._auto_deps: |
264 | | is_swappable_dep = False |
265 | | if dep[0] == "__setting__": |
| 264 | is_swappable_dep = dep[0] == "__setting__" |
| 265 | if is_swappable_dep: |
266 | 266 | # We need to temporarily resolve the swappable dependency to prevent |
267 | 267 | # circular references. While keeping the dependency checks on the |
268 | 268 | # resolved model we still add the swappable dependencies. |
… |
… |
class MigrationAutodetector:
|
270 | 270 | resolved_app_label, resolved_object_name = getattr(settings, dep[1]).split('.') |
271 | 271 | original_dep = dep |
272 | 272 | dep = (resolved_app_label, resolved_object_name.lower(), dep[2], dep[3]) |
273 | | is_swappable_dep = True |
274 | 273 | if dep[0] != app_label and dep[0] != "__setting__": |
275 | 274 | # External app dependency. See if it's not yet |
276 | 275 | # satisfied. |
… |
… |
class MigrationAutodetector:
|
831 | 830 | dependencies.extend(self._get_dependencies_for_foreign_key(field)) |
832 | 831 | # You can't just add NOT NULL fields with no default or fields |
833 | 832 | # which don't allow empty strings as default. |
834 | | preserve_default = True |
835 | 833 | time_fields = (models.DateField, models.DateTimeField, models.TimeField) |
836 | | if (not field.null and not field.has_default() and |
837 | | not field.many_to_many and |
838 | | not (field.blank and field.empty_strings_allowed) and |
839 | | not (isinstance(field, time_fields) and field.auto_now)): |
| 834 | preserve_default = (field.null or field.has_default() or field.many_to_many or |
| 835 | (field.blank and field.empty_strings_allowed) or |
| 836 | (isinstance(field, time_fields) and field.auto_now)) |
| 837 | if not preserve_default: |
840 | 838 | field = field.clone() |
841 | 839 | if isinstance(field, time_fields) and field.auto_now_add: |
842 | 840 | field.default = self.questioner.ask_auto_now_add_addition(field_name, model_name) |
843 | 841 | else: |
844 | 842 | field.default = self.questioner.ask_not_null_addition(field_name, model_name) |
845 | | preserve_default = False |
846 | 843 | self.add_operation( |
847 | 844 | app_label, |
848 | 845 | operations.AddField( |
-
diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py
a
|
b
|
class MigrationGraph:
|
367 | 367 | plan = [] |
368 | 368 | for node in nodes: |
369 | 369 | for migration in self.forwards_plan(node): |
370 | | if migration not in plan: |
371 | | if not at_end and migration in nodes: |
372 | | continue |
| 370 | if migration in plan or at_end or migration not in nodes: |
373 | 371 | plan.append(migration) |
374 | 372 | project_state = ProjectState(real_apps=real_apps) |
375 | 373 | for node in plan: |
-
diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py
a
|
b
|
class MigrationLoader:
|
172 | 172 | dependencies find the correct root node. |
173 | 173 | """ |
174 | 174 | for parent in migration.dependencies: |
175 | | if parent[0] != key[0] or parent[1] == '__first__': |
| 175 | if parent[0] == key[0] and parent[1] != '__first__': |
176 | 176 | # Ignore __first__ references to the same app (#22325). |
177 | | continue |
178 | | self.graph.add_dependency(migration, key, parent, skip_validation=True) |
| 177 | self.graph.add_dependency(migration, key, parent, skip_validation=True) |
179 | 178 | |
180 | 179 | def add_external_dependencies(self, key, migration): |
181 | 180 | for parent in migration.dependencies: |
-
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
a
|
b
|
class RelatedField(FieldCacheMixin, Field):
|
109 | 109 | related_name = self.remote_field.related_name |
110 | 110 | if related_name is None: |
111 | 111 | return [] |
112 | | is_valid_id = True |
113 | | if keyword.iskeyword(related_name): |
114 | | is_valid_id = False |
115 | | if not related_name.isidentifier(): |
116 | | is_valid_id = False |
| 112 | is_valid_id = not keyword.iskeyword(related_name) and related_name.isidentifier() |
117 | 113 | if not (is_valid_id or related_name.endswith('+')): |
118 | 114 | return [ |
119 | 115 | checks.Error( |
-
diff --git a/django/db/models/options.py b/django/db/models/options.py
a
|
b
|
class Options:
|
753 | 753 | |
754 | 754 | # We must keep track of which models we have already seen. Otherwise we |
755 | 755 | # could include the same field multiple times from different models. |
756 | | topmost_call = False |
757 | | if seen_models is None: |
| 756 | topmost_call = seen_models is None |
| 757 | if topmost_call: |
758 | 758 | seen_models = set() |
759 | | topmost_call = True |
760 | 759 | seen_models.add(self.model) |
761 | 760 | |
762 | 761 | # Creates a cache key composed of all arguments |
… |
… |
class Options:
|
785 | 784 | for obj in parent._meta._get_fields( |
786 | 785 | forward=forward, reverse=reverse, include_parents=include_parents, |
787 | 786 | include_hidden=include_hidden, seen_models=seen_models): |
788 | | if getattr(obj, 'parent_link', False) and obj.model != self.concrete_model: |
789 | | continue |
790 | | fields.append(obj) |
| 787 | if not getattr(obj, 'parent_link', False) or obj.model == self.concrete_model: |
| 788 | fields.append(obj) |
791 | 789 | if reverse and not self.proxy: |
792 | 790 | # Tree is computed once and cached until the app cache is expired. |
793 | 791 | # It is composed of a list of fields pointing to the current model |
-
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
a
|
b
|
class SQLCompiler:
|
114 | 114 | for col in cols: |
115 | 115 | expressions.append(col) |
116 | 116 | for expr, (sql, params, is_ref) in order_by: |
117 | | if expr.contains_aggregate: |
118 | | continue |
119 | | # We can skip References to select clause, as all expressions in |
120 | | # the select clause are already part of the group by. |
121 | | if is_ref: |
122 | | continue |
123 | | expressions.extend(expr.get_source_expressions()) |
| 117 | if not expr.contains_aggregate and not is_ref: |
| 118 | # We can skip References to select clause, as all expressions in |
| 119 | # the select clause are already part of the group by. |
| 120 | expressions.extend(expr.get_source_expressions()) |
124 | 121 | having_group_by = self.having.get_group_by_cols() if self.having else () |
125 | 122 | for expr in having_group_by: |
126 | 123 | expressions.append(expr) |
… |
… |
class SQLCompiler:
|
283 | 280 | continue |
284 | 281 | |
285 | 282 | col, order = get_order_dir(field, asc) |
286 | | descending = True if order == 'DESC' else False |
| 283 | descending = order == 'DESC' |
287 | 284 | |
288 | 285 | if col in self.query.annotation_select: |
289 | 286 | # Reference to expression in SELECT clause |
… |
… |
class SQLCompiler:
|
646 | 643 | The 'name' is of the form 'field1__field2__...__fieldN'. |
647 | 644 | """ |
648 | 645 | name, order = get_order_dir(name, default_order) |
649 | | descending = True if order == 'DESC' else False |
| 646 | descending = order == 'DESC' |
650 | 647 | pieces = name.split(LOOKUP_SEP) |
651 | 648 | field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias) |
652 | 649 | |
… |
… |
class SQLCompiler:
|
747 | 744 | # included in the related selection. |
748 | 745 | fields_found = set() |
749 | 746 | if requested is None: |
750 | | if isinstance(self.query.select_related, dict): |
| 747 | restricted = isinstance(self.query.select_related, dict) |
| 748 | if restricted: |
751 | 749 | requested = self.query.select_related |
752 | | restricted = True |
753 | | else: |
754 | | restricted = False |
755 | 750 | |
756 | 751 | def get_related_klass_infos(klass_info, related_klass_infos): |
757 | 752 | klass_info['related_klass_infos'] = related_klass_infos |
-
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
a
|
b
|
class Query:
|
666 | 666 | workset = {} |
667 | 667 | for model, values in seen.items(): |
668 | 668 | for field in model._meta.local_fields: |
669 | | if field in values: |
670 | | continue |
671 | | m = field.model._meta.concrete_model |
672 | | add_to_dict(workset, m, field) |
| 669 | if field not in values: |
| 670 | m = field.model._meta.concrete_model |
| 671 | add_to_dict(workset, m, field) |
673 | 672 | for model, values in must_include.items(): |
674 | 673 | # If we haven't included a model in workset, we don't add the |
675 | 674 | # corresponding must_include fields for that model, since an |
-
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
a
|
b
|
def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
|
437 | 437 | |
438 | 438 | def all_valid(formsets): |
439 | 439 | """Return True if every formset in formsets is valid.""" |
440 | | valid = True |
441 | | for formset in formsets: |
442 | | if not formset.is_valid(): |
443 | | valid = False |
444 | | return valid |
| 440 | return all(formset.is_valid() for formset in formsets) |
-
diff --git a/django/forms/models.py b/django/forms/models.py
a
|
b
|
class BaseModelFormSet(BaseFormSet):
|
587 | 587 | return field.to_python |
588 | 588 | |
589 | 589 | def _construct_form(self, i, **kwargs): |
590 | | pk_required = False |
591 | | if i < self.initial_form_count(): |
592 | | pk_required = True |
| 590 | pk_required = i < self.initial_form_count() |
| 591 | if pk_required: |
593 | 592 | if self.is_bound: |
594 | 593 | pk_key = '%s-%s' % (self.add_prefix(i), self.model._meta.pk.name) |
595 | 594 | try: |
-
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
a
|
b
|
class ChoiceWidget(Widget):
|
599 | 599 | str(subvalue) in value and |
600 | 600 | (not has_selected or self.allow_multiple_selected) |
601 | 601 | ) |
602 | | if selected and not has_selected: |
603 | | has_selected = True |
| 602 | has_selected |= selected |
604 | 603 | subgroup.append(self.create_option( |
605 | 604 | name, subvalue, sublabel, selected, index, |
606 | 605 | subindex=subindex, attrs=attrs, |
-
diff --git a/django/utils/cache.py b/django/utils/cache.py
a
|
b
|
def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cach
|
376 | 376 | headerlist = [] |
377 | 377 | for header in cc_delim_re.split(response['Vary']): |
378 | 378 | header = header.upper().replace('-', '_') |
379 | | if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant: |
380 | | continue |
381 | | headerlist.append('HTTP_' + header) |
| 379 | if header != 'ACCEPT_LANGUAGE' or not is_accept_language_redundant: |
| 380 | headerlist.append('HTTP_' + header) |
382 | 381 | headerlist.sort() |
383 | 382 | cache.set(cache_key, headerlist, cache_timeout) |
384 | 383 | return _generate_cache_key(request, request.method, headerlist, key_prefix) |
-
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
a
|
b
|
class DictWrapper(dict):
|
275 | 275 | present). If the prefix is present, pass the value through self.func |
276 | 276 | before returning, otherwise return the raw value. |
277 | 277 | """ |
278 | | if key.startswith(self.prefix): |
279 | | use_func = True |
| 278 | use_func = key.startswith(self.prefix) |
| 279 | if use_func: |
280 | 280 | key = key[len(self.prefix):] |
281 | | else: |
282 | | use_func = False |
283 | 281 | value = super().__getitem__(key) |
284 | 282 | if use_func: |
285 | 283 | return self.func(value) |
-
diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py
a
|
b
|
def normalize(pattern):
|
176 | 176 | |
177 | 177 | if consume_next: |
178 | 178 | ch, escaped = next(pattern_iter) |
179 | | else: |
180 | | consume_next = True |
| 179 | consume_next = True |
181 | 180 | except StopIteration: |
182 | 181 | pass |
183 | 182 | except NotImplementedError: |
-
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
a
|
b
|
templates used by the :class:`ModelAdmin` views:
|
1694 | 1694 | def get_formsets_with_inlines(self, request, obj=None): |
1695 | 1695 | for inline in self.get_inline_instances(request, obj): |
1696 | 1696 | # hide MyInline in the add view |
1697 | | if isinstance(inline, MyInline) and obj is None: |
1698 | | continue |
1699 | | yield inline.get_formset(request, obj), inline |
| 1697 | if not isinstance(inline, MyInline) or obj is not None: |
| 1698 | yield inline.get_formset(request, obj), inline |
1700 | 1699 | |
1701 | 1700 | .. method:: ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs) |
1702 | 1701 | |
-
diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py
a
|
b
|
class DistanceTest(TestCase):
|
81 | 81 | # Now performing the `dwithin` queries on a geodetic coordinate system. |
82 | 82 | for dist in au_dists: |
83 | 83 | with self.subTest(dist=dist): |
84 | | if isinstance(dist, D) and not oracle: |
85 | | type_error = True |
86 | | else: |
87 | | type_error = False |
| 84 | type_error = isinstance(dist, D) and not oracle |
88 | 85 | |
89 | 86 | if isinstance(dist, tuple): |
90 | 87 | if oracle or spatialite: |
-
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py
a
|
b
|
def get_max_column_name_length():
|
17 | 17 | for db in settings.DATABASES: |
18 | 18 | connection = connections[db] |
19 | 19 | max_name_length = connection.ops.max_name_length() |
20 | | if max_name_length is None or connection.features.truncates_names: |
21 | | continue |
22 | | else: |
23 | | if allowed_len is None: |
24 | | allowed_len = max_name_length |
25 | | db_alias = db |
26 | | elif max_name_length < allowed_len: |
| 20 | if max_name_length is not None and not connection.features.truncates_names: |
| 21 | if allowed_len is None or max_name_length < allowed_len: |
27 | 22 | allowed_len = max_name_length |
28 | 23 | db_alias = db |
29 | 24 | |
-
diff --git a/tests/messages_tests/base.py b/tests/messages_tests/base.py
a
|
b
|
class BaseTests:
|
252 | 252 | def test_middleware_disabled_fail_silently(self): |
253 | 253 | """ |
254 | 254 | When the middleware is disabled, an exception is not raised |
255 | | if 'fail_silently' = True |
| 255 | if 'fail_silently' == True |
256 | 256 | """ |
257 | 257 | data = { |
258 | 258 | 'messages': ['Test message %d' % x for x in range(5)], |
-
diff --git a/tests/runtests.py b/tests/runtests.py
a
|
b
|
def get_test_modules():
|
85 | 85 | |
86 | 86 | for modpath, dirpath in discovery_paths: |
87 | 87 | for f in os.listdir(dirpath): |
88 | | if ('.' in f or |
89 | | os.path.basename(f) in SUBDIRS_TO_SKIP or |
90 | | os.path.isfile(f) or |
91 | | not os.path.exists(os.path.join(dirpath, f, '__init__.py'))): |
92 | | continue |
93 | | modules.append((modpath, f)) |
| 88 | if ('.' not in f and |
| 89 | os.path.basename(f) not in SUBDIRS_TO_SKIP and |
| 90 | not os.path.isfile(f) and |
| 91 | os.path.exists(os.path.join(dirpath, f, '__init__.py'))): |
| 92 | modules.append((modpath, f)) |
94 | 93 | return modules |
95 | 94 | |
96 | 95 | |
… |
… |
def setup(verbosity, test_labels, parallel):
|
189 | 188 | # if the module (or an ancestor) was named on the command line, or |
190 | 189 | # no modules were named (i.e., run all), import |
191 | 190 | # this module and add it to INSTALLED_APPS. |
192 | | if not test_labels: |
193 | | module_found_in_labels = True |
194 | | else: |
195 | | module_found_in_labels = any( |
196 | | # exact match or ancestor match |
197 | | module_label == label or module_label.startswith(label + '.') |
198 | | for label in test_labels_set) |
| 191 | module_found_in_labels = not test_labels or any( |
| 192 | # exact match or ancestor match |
| 193 | module_label == label or module_label.startswith(label + '.') |
| 194 | for label in test_labels_set) |
199 | 195 | |
200 | 196 | if module_name in CONTRIB_TESTS_TO_APPS and module_found_in_labels: |
201 | 197 | settings.INSTALLED_APPS.append(CONTRIB_TESTS_TO_APPS[module_name]) |