Refs #23919 -- Replaced kwargs.pop() with keyword-only arguments.
This commit is contained in:
parent
0ec4dc91e0
commit
8838d4dd49
|
@ -6,7 +6,7 @@ from django.urls import LocaleRegexURLResolver, get_resolver
|
||||||
from django.views.i18n import set_language
|
from django.views.i18n import set_language
|
||||||
|
|
||||||
|
|
||||||
def i18n_patterns(*urls, **kwargs):
|
def i18n_patterns(*urls, prefix_default_language=True):
|
||||||
"""
|
"""
|
||||||
Adds the language code prefix to every URL pattern within this
|
Adds the language code prefix to every URL pattern within this
|
||||||
function. This may only be used in the root URLconf, not in an included
|
function. This may only be used in the root URLconf, not in an included
|
||||||
|
@ -14,8 +14,6 @@ def i18n_patterns(*urls, **kwargs):
|
||||||
"""
|
"""
|
||||||
if not settings.USE_I18N:
|
if not settings.USE_I18N:
|
||||||
return list(urls)
|
return list(urls)
|
||||||
prefix_default_language = kwargs.pop('prefix_default_language', True)
|
|
||||||
assert not kwargs, 'Unexpected kwargs for i18n_patterns(): %s' % kwargs
|
|
||||||
return [LocaleRegexURLResolver(list(urls), prefix_default_language=prefix_default_language)]
|
return [LocaleRegexURLResolver(list(urls), prefix_default_language=prefix_default_language)]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
def register(*models, **kwargs):
|
def register(*models, site=None):
|
||||||
"""
|
"""
|
||||||
Registers the given model(s) classes and wrapped ModelAdmin class with
|
Registers the given model(s) classes and wrapped ModelAdmin class with
|
||||||
admin site:
|
admin site:
|
||||||
|
@ -7,17 +7,16 @@ def register(*models, **kwargs):
|
||||||
class AuthorAdmin(admin.ModelAdmin):
|
class AuthorAdmin(admin.ModelAdmin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
A kwarg of `site` can be passed as the admin site, otherwise the default
|
The `site` kwarg is an admin site to use instead of the default admin site.
|
||||||
admin site will be used.
|
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin import ModelAdmin
|
from django.contrib.admin import ModelAdmin
|
||||||
from django.contrib.admin.sites import site, AdminSite
|
from django.contrib.admin.sites import site as default_site, AdminSite
|
||||||
|
|
||||||
def _model_admin_wrapper(admin_class):
|
def _model_admin_wrapper(admin_class):
|
||||||
if not models:
|
if not models:
|
||||||
raise ValueError('At least one model must be passed to register.')
|
raise ValueError('At least one model must be passed to register.')
|
||||||
|
|
||||||
admin_site = kwargs.pop('site', site)
|
admin_site = site or default_site
|
||||||
|
|
||||||
if not isinstance(admin_site, AdminSite):
|
if not isinstance(admin_site, AdminSite):
|
||||||
raise ValueError('site must subclass AdminSite')
|
raise ValueError('site must subclass AdminSite')
|
||||||
|
|
|
@ -496,10 +496,8 @@ def create_generic_related_manager(superclass, rel):
|
||||||
self.object_id_field_name: self.pk_val,
|
self.object_id_field_name: self.pk_val,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __call__(self, **kwargs):
|
def __call__(self, *, manager):
|
||||||
# We use **kwargs rather than a kwarg argument to enforce the
|
manager = getattr(self.model, manager)
|
||||||
# `manager='manager_name'` syntax.
|
|
||||||
manager = getattr(self.model, kwargs.pop('manager'))
|
|
||||||
manager_class = create_generic_related_manager(manager.__class__, rel)
|
manager_class = create_generic_related_manager(manager.__class__, rel)
|
||||||
return manager_class(instance=self.instance)
|
return manager_class(instance=self.instance)
|
||||||
do_not_call_in_templates = True
|
do_not_call_in_templates = True
|
||||||
|
@ -542,8 +540,7 @@ def create_generic_related_manager(superclass, rel):
|
||||||
False,
|
False,
|
||||||
self.prefetch_cache_name)
|
self.prefetch_cache_name)
|
||||||
|
|
||||||
def add(self, *objs, **kwargs):
|
def add(self, *objs, bulk=True):
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
|
|
||||||
def check_and_update_obj(obj):
|
def check_and_update_obj(obj):
|
||||||
|
@ -576,15 +573,13 @@ def create_generic_related_manager(superclass, rel):
|
||||||
obj.save()
|
obj.save()
|
||||||
add.alters_data = True
|
add.alters_data = True
|
||||||
|
|
||||||
def remove(self, *objs, **kwargs):
|
def remove(self, *objs, bulk=True):
|
||||||
if not objs:
|
if not objs:
|
||||||
return
|
return
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
self._clear(self.filter(pk__in=[o.pk for o in objs]), bulk)
|
self._clear(self.filter(pk__in=[o.pk for o in objs]), bulk)
|
||||||
remove.alters_data = True
|
remove.alters_data = True
|
||||||
|
|
||||||
def clear(self, **kwargs):
|
def clear(self, *, bulk=True):
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
self._clear(self, bulk)
|
self._clear(self, bulk)
|
||||||
clear.alters_data = True
|
clear.alters_data = True
|
||||||
|
|
||||||
|
@ -601,14 +596,11 @@ def create_generic_related_manager(superclass, rel):
|
||||||
obj.delete()
|
obj.delete()
|
||||||
_clear.alters_data = True
|
_clear.alters_data = True
|
||||||
|
|
||||||
def set(self, objs, **kwargs):
|
def set(self, objs, *, bulk=True, clear=False):
|
||||||
# Force evaluation of `objs` in case it's a queryset whose value
|
# Force evaluation of `objs` in case it's a queryset whose value
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
objs = tuple(objs)
|
objs = tuple(objs)
|
||||||
|
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
clear = kwargs.pop('clear', False)
|
|
||||||
|
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
if clear:
|
if clear:
|
||||||
|
|
|
@ -60,11 +60,10 @@ class ContentTypeManager(models.Manager):
|
||||||
self._add_to_cache(self.db, ct)
|
self._add_to_cache(self.db, ct)
|
||||||
return ct
|
return ct
|
||||||
|
|
||||||
def get_for_models(self, *models, **kwargs):
|
def get_for_models(self, *models, for_concrete_models=True):
|
||||||
"""
|
"""
|
||||||
Given *models, returns a dictionary mapping {model: content_type}.
|
Given *models, returns a dictionary mapping {model: content_type}.
|
||||||
"""
|
"""
|
||||||
for_concrete_models = kwargs.pop('for_concrete_models', True)
|
|
||||||
results = {}
|
results = {}
|
||||||
# Models that aren't already in the cache.
|
# Models that aren't already in the cache.
|
||||||
needed_app_labels = set()
|
needed_app_labels = set()
|
||||||
|
|
|
@ -263,7 +263,8 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField):
|
||||||
# The OpenGIS Geometry name.
|
# The OpenGIS Geometry name.
|
||||||
geom_type = 'GEOMETRY'
|
geom_type = 'GEOMETRY'
|
||||||
|
|
||||||
def __init__(self, verbose_name=None, dim=2, geography=False, **kwargs):
|
def __init__(self, verbose_name=None, dim=2, geography=False, *, extent=(-180.0, -90.0, 180.0, 90.0),
|
||||||
|
tolerance=0.05, **kwargs):
|
||||||
"""
|
"""
|
||||||
The initialization function for geometry fields. In addition to the
|
The initialization function for geometry fields. In addition to the
|
||||||
parameters from BaseSpatialField, it takes the following as keyword
|
parameters from BaseSpatialField, it takes the following as keyword
|
||||||
|
@ -289,8 +290,8 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField):
|
||||||
|
|
||||||
# Oracle-specific private attributes for creating the entry in
|
# Oracle-specific private attributes for creating the entry in
|
||||||
# `USER_SDO_GEOM_METADATA`
|
# `USER_SDO_GEOM_METADATA`
|
||||||
self._extent = kwargs.pop('extent', (-180.0, -90.0, 180.0, 90.0))
|
self._extent = extent
|
||||||
self._tolerance = kwargs.pop('tolerance', 0.05)
|
self._tolerance = tolerance
|
||||||
|
|
||||||
super().__init__(verbose_name=verbose_name, **kwargs)
|
super().__init__(verbose_name=verbose_name, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,10 @@ class GeometryField(forms.Field):
|
||||||
'to the SRID of the geometry form field.'),
|
'to the SRID of the geometry form field.'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, *, srid=None, geom_type=None, **kwargs):
|
||||||
# Pop out attributes from the database field, or use sensible
|
self.srid = srid
|
||||||
# defaults (e.g., allow None).
|
if geom_type is not None:
|
||||||
self.srid = kwargs.pop('srid', None)
|
self.geom_type = geom_type
|
||||||
self.geom_type = kwargs.pop('geom_type', self.geom_type)
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.widget.attrs['geom_type'] = self.geom_type
|
self.widget.attrs['geom_type'] = self.geom_type
|
||||||
|
|
||||||
|
|
|
@ -147,11 +147,14 @@ class GEOSFuncFactory:
|
||||||
restype = None
|
restype = None
|
||||||
errcheck = None
|
errcheck = None
|
||||||
|
|
||||||
def __init__(self, func_name, *args, **kwargs):
|
def __init__(self, func_name, *args, restype=None, errcheck=None, argtypes=None, **kwargs):
|
||||||
self.func_name = func_name
|
self.func_name = func_name
|
||||||
self.restype = kwargs.pop('restype', self.restype)
|
if restype is not None:
|
||||||
self.errcheck = kwargs.pop('errcheck', self.errcheck)
|
self.restype = restype
|
||||||
self.argtypes = kwargs.pop('argtypes', self.argtypes)
|
if errcheck is not None:
|
||||||
|
self.errcheck = errcheck
|
||||||
|
if argtypes is not None:
|
||||||
|
self.argtypes = argtypes
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.func = None
|
self.func = None
|
||||||
|
|
|
@ -125,13 +125,11 @@ class SearchQueryCombinable:
|
||||||
|
|
||||||
|
|
||||||
class SearchQuery(SearchQueryCombinable, Value):
|
class SearchQuery(SearchQueryCombinable, Value):
|
||||||
invert = False
|
|
||||||
_output_field = SearchQueryField()
|
_output_field = SearchQueryField()
|
||||||
config = None
|
|
||||||
|
|
||||||
def __init__(self, value, output_field=None, **extra):
|
def __init__(self, value, output_field=None, *, config=None, invert=False):
|
||||||
self.config = extra.pop('config', self.config)
|
self.config = config
|
||||||
self.invert = extra.pop('invert', self.invert)
|
self.invert = invert
|
||||||
super().__init__(value, output_field=output_field)
|
super().__init__(value, output_field=output_field)
|
||||||
|
|
||||||
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
||||||
|
@ -161,11 +159,7 @@ class SearchQuery(SearchQueryCombinable, Value):
|
||||||
return combined
|
return combined
|
||||||
|
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
extra = {
|
return type(self)(self.value, config=self.config, invert=not self.invert)
|
||||||
'invert': not self.invert,
|
|
||||||
'config': self.config,
|
|
||||||
}
|
|
||||||
return type(self)(self.value, **extra)
|
|
||||||
|
|
||||||
|
|
||||||
class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression):
|
class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression):
|
||||||
|
|
|
@ -10,10 +10,10 @@ from django.core.mail.backends.console import \
|
||||||
|
|
||||||
|
|
||||||
class EmailBackend(ConsoleEmailBackend):
|
class EmailBackend(ConsoleEmailBackend):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, file_path=None, **kwargs):
|
||||||
self._fname = None
|
self._fname = None
|
||||||
if 'file_path' in kwargs:
|
if file_path is not None:
|
||||||
self.file_path = kwargs.pop('file_path')
|
self.file_path = file_path
|
||||||
else:
|
else:
|
||||||
self.file_path = getattr(settings, 'EMAIL_FILE_PATH', None)
|
self.file_path = getattr(settings, 'EMAIL_FILE_PATH', None)
|
||||||
# Make sure self.file_path is a string.
|
# Make sure self.file_path is a string.
|
||||||
|
|
|
@ -62,19 +62,18 @@ class Serializer:
|
||||||
progress_class = ProgressBar
|
progress_class = ProgressBar
|
||||||
stream_class = StringIO
|
stream_class = StringIO
|
||||||
|
|
||||||
def serialize(self, queryset, **options):
|
def serialize(self, queryset, *, stream=None, fields=None, use_natural_foreign_keys=False,
|
||||||
|
use_natural_primary_keys=False, progress_output=None, object_count=0, **options):
|
||||||
"""
|
"""
|
||||||
Serialize a queryset.
|
Serialize a queryset.
|
||||||
"""
|
"""
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
self.stream = options.pop("stream", self.stream_class())
|
self.stream = stream if stream is not None else self.stream_class()
|
||||||
self.selected_fields = options.pop("fields", None)
|
self.selected_fields = fields
|
||||||
self.use_natural_foreign_keys = options.pop('use_natural_foreign_keys', False)
|
self.use_natural_foreign_keys = use_natural_foreign_keys
|
||||||
self.use_natural_primary_keys = options.pop('use_natural_primary_keys', False)
|
self.use_natural_primary_keys = use_natural_primary_keys
|
||||||
progress_bar = self.progress_class(
|
progress_bar = self.progress_class(progress_output, object_count)
|
||||||
options.pop('progress_output', None), options.pop('object_count', 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.start_serialization()
|
self.start_serialization()
|
||||||
self.first = True
|
self.first = True
|
||||||
|
|
|
@ -79,15 +79,13 @@ class Serializer(base.Serializer):
|
||||||
return self.objects
|
return self.objects
|
||||||
|
|
||||||
|
|
||||||
def Deserializer(object_list, **options):
|
def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False, **options):
|
||||||
"""
|
"""
|
||||||
Deserialize simple Python objects back into Django ORM instances.
|
Deserialize simple Python objects back into Django ORM instances.
|
||||||
|
|
||||||
It's expected that you pass the Python objects themselves (instead of a
|
It's expected that you pass the Python objects themselves (instead of a
|
||||||
stream or a string) to the constructor
|
stream or a string) to the constructor
|
||||||
"""
|
"""
|
||||||
db = options.pop('using', DEFAULT_DB_ALIAS)
|
|
||||||
ignore = options.pop('ignorenonexistent', False)
|
|
||||||
field_names_cache = {} # Model: <list of field_names>
|
field_names_cache = {} # Model: <list of field_names>
|
||||||
|
|
||||||
for d in object_list:
|
for d in object_list:
|
||||||
|
@ -95,7 +93,7 @@ def Deserializer(object_list, **options):
|
||||||
try:
|
try:
|
||||||
Model = _get_model(d["model"])
|
Model = _get_model(d["model"])
|
||||||
except base.DeserializationError:
|
except base.DeserializationError:
|
||||||
if ignore:
|
if ignorenonexistent:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
@ -114,7 +112,7 @@ def Deserializer(object_list, **options):
|
||||||
# Handle each field
|
# Handle each field
|
||||||
for (field_name, field_value) in d["fields"].items():
|
for (field_name, field_value) in d["fields"].items():
|
||||||
|
|
||||||
if ignore and field_name not in field_names:
|
if ignorenonexistent and field_name not in field_names:
|
||||||
# skip fields no longer on model
|
# skip fields no longer on model
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -131,7 +129,7 @@ def Deserializer(object_list, **options):
|
||||||
if hasattr(model._default_manager, 'get_by_natural_key'):
|
if hasattr(model._default_manager, 'get_by_natural_key'):
|
||||||
def m2m_convert(value):
|
def m2m_convert(value):
|
||||||
if hasattr(value, '__iter__') and not isinstance(value, str):
|
if hasattr(value, '__iter__') and not isinstance(value, str):
|
||||||
return model._default_manager.db_manager(db).get_by_natural_key(*value).pk
|
return model._default_manager.db_manager(using).get_by_natural_key(*value).pk
|
||||||
else:
|
else:
|
||||||
return force_text(model._meta.pk.to_python(value), strings_only=True)
|
return force_text(model._meta.pk.to_python(value), strings_only=True)
|
||||||
else:
|
else:
|
||||||
|
@ -154,7 +152,7 @@ def Deserializer(object_list, **options):
|
||||||
field_name = field.remote_field.field_name
|
field_name = field.remote_field.field_name
|
||||||
if hasattr(default_manager, 'get_by_natural_key'):
|
if hasattr(default_manager, 'get_by_natural_key'):
|
||||||
if hasattr(field_value, '__iter__') and not isinstance(field_value, str):
|
if hasattr(field_value, '__iter__') and not isinstance(field_value, str):
|
||||||
obj = default_manager.db_manager(db).get_by_natural_key(*field_value)
|
obj = default_manager.db_manager(using).get_by_natural_key(*field_value)
|
||||||
value = getattr(obj, field.remote_field.field_name)
|
value = getattr(obj, field.remote_field.field_name)
|
||||||
# If this is a natural foreign key to an object that
|
# If this is a natural foreign key to an object that
|
||||||
# has a FK/O2O as the foreign key, use the FK value
|
# has a FK/O2O as the foreign key, use the FK value
|
||||||
|
@ -177,7 +175,7 @@ def Deserializer(object_list, **options):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
|
raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
|
||||||
|
|
||||||
obj = base.build_instance(Model, data, db)
|
obj = base.build_instance(Model, data, using)
|
||||||
yield base.DeserializedObject(obj, m2m_data)
|
yield base.DeserializedObject(obj, m2m_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -157,11 +157,11 @@ class Deserializer(base.Deserializer):
|
||||||
Deserialize XML.
|
Deserialize XML.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, stream_or_string, **options):
|
def __init__(self, stream_or_string, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False, **options):
|
||||||
super().__init__(stream_or_string, **options)
|
super().__init__(stream_or_string, **options)
|
||||||
self.event_stream = pulldom.parse(self.stream, self._make_parser())
|
self.event_stream = pulldom.parse(self.stream, self._make_parser())
|
||||||
self.db = options.pop('using', DEFAULT_DB_ALIAS)
|
self.db = using
|
||||||
self.ignore = options.pop('ignorenonexistent', False)
|
self.ignore = ignorenonexistent
|
||||||
|
|
||||||
def _make_parser(self):
|
def _make_parser(self):
|
||||||
"""Create a hardened XML parser (no custom/external entities)."""
|
"""Create a hardened XML parser (no custom/external entities)."""
|
||||||
|
|
|
@ -59,10 +59,10 @@ class WSGIServer(simple_server.WSGIServer):
|
||||||
|
|
||||||
request_queue_size = 10
|
request_queue_size = 10
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, ipv6=False, allow_reuse_address=True, **kwargs):
|
||||||
if kwargs.pop('ipv6', False):
|
if ipv6:
|
||||||
self.address_family = socket.AF_INET6
|
self.address_family = socket.AF_INET6
|
||||||
self.allow_reuse_address = kwargs.pop('allow_reuse_address', True)
|
self.allow_reuse_address = allow_reuse_address
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def server_bind(self):
|
def server_bind(self):
|
||||||
|
|
|
@ -10,15 +10,13 @@ class IntervalToSeconds(Func):
|
||||||
EXTRACT(second from %(expressions)s)
|
EXTRACT(second from %(expressions)s)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, expression, **extra):
|
def __init__(self, expression, *, output_field=None, **extra):
|
||||||
output_field = extra.pop('output_field', DecimalField())
|
super().__init__(expression, output_field=output_field or DecimalField(), **extra)
|
||||||
super().__init__(expression, output_field=output_field, **extra)
|
|
||||||
|
|
||||||
|
|
||||||
class SecondsToInterval(Func):
|
class SecondsToInterval(Func):
|
||||||
function = 'NUMTODSINTERVAL'
|
function = 'NUMTODSINTERVAL'
|
||||||
template = "%(function)s(%(expressions)s, 'SECOND')"
|
template = "%(function)s(%(expressions)s, 'SECOND')"
|
||||||
|
|
||||||
def __init__(self, expression, **extra):
|
def __init__(self, expression, *, output_field=None, **extra):
|
||||||
output_field = extra.pop('output_field', DurationField())
|
super().__init__(expression, output_field=output_field or DurationField(), **extra)
|
||||||
super().__init__(expression, output_field=output_field, **extra)
|
|
||||||
|
|
|
@ -506,7 +506,7 @@ class Func(Expression):
|
||||||
arg_joiner = ', '
|
arg_joiner = ', '
|
||||||
arity = None # The number of arguments the function accepts.
|
arity = None # The number of arguments the function accepts.
|
||||||
|
|
||||||
def __init__(self, *expressions, **extra):
|
def __init__(self, *expressions, output_field=None, **extra):
|
||||||
if self.arity is not None and len(expressions) != self.arity:
|
if self.arity is not None and len(expressions) != self.arity:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"'%s' takes exactly %s %s (%s given)" % (
|
"'%s' takes exactly %s %s (%s given)" % (
|
||||||
|
@ -516,7 +516,6 @@ class Func(Expression):
|
||||||
len(expressions),
|
len(expressions),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
output_field = extra.pop('output_field', None)
|
|
||||||
super().__init__(output_field=output_field)
|
super().__init__(output_field=output_field)
|
||||||
self.source_expressions = self._parse_expressions(*expressions)
|
self.source_expressions = self._parse_expressions(*expressions)
|
||||||
self.extra = extra
|
self.extra = extra
|
||||||
|
@ -828,11 +827,9 @@ class Case(Expression):
|
||||||
template = 'CASE %(cases)s ELSE %(default)s END'
|
template = 'CASE %(cases)s ELSE %(default)s END'
|
||||||
case_joiner = ' '
|
case_joiner = ' '
|
||||||
|
|
||||||
def __init__(self, *cases, **extra):
|
def __init__(self, *cases, default=None, output_field=None, **extra):
|
||||||
if not all(isinstance(case, When) for case in cases):
|
if not all(isinstance(case, When) for case in cases):
|
||||||
raise TypeError("Positional arguments must all be When objects.")
|
raise TypeError("Positional arguments must all be When objects.")
|
||||||
default = extra.pop('default', None)
|
|
||||||
output_field = extra.pop('output_field', None)
|
|
||||||
super().__init__(output_field)
|
super().__init__(output_field)
|
||||||
self.cases = list(cases)
|
self.cases = list(cases)
|
||||||
self.default = self._parse_expressions(default)[0]
|
self.default = self._parse_expressions(default)[0]
|
||||||
|
@ -983,8 +980,8 @@ class Subquery(Expression):
|
||||||
class Exists(Subquery):
|
class Exists(Subquery):
|
||||||
template = 'EXISTS(%(subquery)s)'
|
template = 'EXISTS(%(subquery)s)'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, negated=False, **kwargs):
|
||||||
self.negated = kwargs.pop('negated', False)
|
self.negated = negated
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
|
|
|
@ -2045,15 +2045,11 @@ class SlugField(CharField):
|
||||||
default_validators = [validators.validate_slug]
|
default_validators = [validators.validate_slug]
|
||||||
description = _("Slug (up to %(max_length)s)")
|
description = _("Slug (up to %(max_length)s)")
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, max_length=50, db_index=True, allow_unicode=False, **kwargs):
|
||||||
kwargs['max_length'] = kwargs.get('max_length', 50)
|
self.allow_unicode = allow_unicode
|
||||||
# Set db_index=True unless it's been set manually.
|
|
||||||
if 'db_index' not in kwargs:
|
|
||||||
kwargs['db_index'] = True
|
|
||||||
self.allow_unicode = kwargs.pop('allow_unicode', False)
|
|
||||||
if self.allow_unicode:
|
if self.allow_unicode:
|
||||||
self.default_validators = [validators.validate_unicode_slug]
|
self.default_validators = [validators.validate_unicode_slug]
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, max_length=max_length, db_index=db_index, **kwargs)
|
||||||
|
|
||||||
def deconstruct(self):
|
def deconstruct(self):
|
||||||
name, path, args, kwargs = super().deconstruct()
|
name, path, args, kwargs = super().deconstruct()
|
||||||
|
|
|
@ -922,15 +922,14 @@ class ForeignKey(ForeignObject):
|
||||||
if self.remote_field.field_name is None:
|
if self.remote_field.field_name is None:
|
||||||
self.remote_field.field_name = cls._meta.pk.name
|
self.remote_field.field_name = cls._meta.pk.name
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, *, using=None, **kwargs):
|
||||||
db = kwargs.pop('using', None)
|
|
||||||
if isinstance(self.remote_field.model, str):
|
if isinstance(self.remote_field.model, str):
|
||||||
raise ValueError("Cannot create form field for %r yet, because "
|
raise ValueError("Cannot create form field for %r yet, because "
|
||||||
"its related model %r has not been loaded yet" %
|
"its related model %r has not been loaded yet" %
|
||||||
(self.name, self.remote_field.model))
|
(self.name, self.remote_field.model))
|
||||||
defaults = {
|
defaults = {
|
||||||
'form_class': forms.ModelChoiceField,
|
'form_class': forms.ModelChoiceField,
|
||||||
'queryset': self.remote_field.model._default_manager.using(db),
|
'queryset': self.remote_field.model._default_manager.using(using),
|
||||||
'to_field_name': self.remote_field.field_name,
|
'to_field_name': self.remote_field.field_name,
|
||||||
}
|
}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
|
@ -1609,11 +1608,10 @@ class ManyToManyField(RelatedField):
|
||||||
def save_form_data(self, instance, data):
|
def save_form_data(self, instance, data):
|
||||||
getattr(instance, self.attname).set(data)
|
getattr(instance, self.attname).set(data)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, *, using=None, **kwargs):
|
||||||
db = kwargs.pop('using', None)
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'form_class': forms.ModelMultipleChoiceField,
|
'form_class': forms.ModelMultipleChoiceField,
|
||||||
'queryset': self.remote_field.model._default_manager.using(db),
|
'queryset': self.remote_field.model._default_manager.using(using),
|
||||||
}
|
}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
# If initial is passed in, it's a list of related objects, but the
|
# If initial is passed in, it's a list of related objects, but the
|
||||||
|
|
|
@ -510,10 +510,8 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
|
|
||||||
self.core_filters = {self.field.name: instance}
|
self.core_filters = {self.field.name: instance}
|
||||||
|
|
||||||
def __call__(self, **kwargs):
|
def __call__(self, *, manager):
|
||||||
# We use **kwargs rather than a kwarg argument to enforce the
|
manager = getattr(self.model, manager)
|
||||||
# `manager='manager_name'` syntax.
|
|
||||||
manager = getattr(self.model, kwargs.pop('manager'))
|
|
||||||
manager_class = create_reverse_many_to_one_manager(manager.__class__, rel)
|
manager_class = create_reverse_many_to_one_manager(manager.__class__, rel)
|
||||||
return manager_class(self.instance)
|
return manager_class(self.instance)
|
||||||
do_not_call_in_templates = True
|
do_not_call_in_templates = True
|
||||||
|
@ -569,9 +567,8 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
cache_name = self.field.related_query_name()
|
cache_name = self.field.related_query_name()
|
||||||
return queryset, rel_obj_attr, instance_attr, False, cache_name
|
return queryset, rel_obj_attr, instance_attr, False, cache_name
|
||||||
|
|
||||||
def add(self, *objs, **kwargs):
|
def add(self, *objs, bulk=True):
|
||||||
self._remove_prefetched_objects()
|
self._remove_prefetched_objects()
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
objs = list(objs)
|
objs = list(objs)
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
|
|
||||||
|
@ -622,10 +619,9 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
|
|
||||||
# remove() and clear() are only provided if the ForeignKey can have a value of null.
|
# remove() and clear() are only provided if the ForeignKey can have a value of null.
|
||||||
if rel.field.null:
|
if rel.field.null:
|
||||||
def remove(self, *objs, **kwargs):
|
def remove(self, *objs, bulk=True):
|
||||||
if not objs:
|
if not objs:
|
||||||
return
|
return
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
val = self.field.get_foreign_related_value(self.instance)
|
val = self.field.get_foreign_related_value(self.instance)
|
||||||
old_ids = set()
|
old_ids = set()
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
|
@ -639,8 +635,7 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
self._clear(self.filter(pk__in=old_ids), bulk)
|
self._clear(self.filter(pk__in=old_ids), bulk)
|
||||||
remove.alters_data = True
|
remove.alters_data = True
|
||||||
|
|
||||||
def clear(self, **kwargs):
|
def clear(self, *, bulk=True):
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
self._clear(self, bulk)
|
self._clear(self, bulk)
|
||||||
clear.alters_data = True
|
clear.alters_data = True
|
||||||
|
|
||||||
|
@ -658,14 +653,11 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
||||||
obj.save(update_fields=[self.field.name])
|
obj.save(update_fields=[self.field.name])
|
||||||
_clear.alters_data = True
|
_clear.alters_data = True
|
||||||
|
|
||||||
def set(self, objs, **kwargs):
|
def set(self, objs, *, bulk=True, clear=False):
|
||||||
# Force evaluation of `objs` in case it's a queryset whose value
|
# Force evaluation of `objs` in case it's a queryset whose value
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
objs = tuple(objs)
|
objs = tuple(objs)
|
||||||
|
|
||||||
bulk = kwargs.pop('bulk', True)
|
|
||||||
clear = kwargs.pop('clear', False)
|
|
||||||
|
|
||||||
if self.field.null:
|
if self.field.null:
|
||||||
db = router.db_for_write(self.model, instance=self.instance)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
|
@ -791,10 +783,8 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||||
"a many-to-many relationship can be used." %
|
"a many-to-many relationship can be used." %
|
||||||
instance.__class__.__name__)
|
instance.__class__.__name__)
|
||||||
|
|
||||||
def __call__(self, **kwargs):
|
def __call__(self, *, manager):
|
||||||
# We use **kwargs rather than a kwarg argument to enforce the
|
manager = getattr(self.model, manager)
|
||||||
# `manager='manager_name'` syntax.
|
|
||||||
manager = getattr(self.model, kwargs.pop('manager'))
|
|
||||||
manager_class = create_forward_many_to_many_manager(manager.__class__, rel, reverse)
|
manager_class = create_forward_many_to_many_manager(manager.__class__, rel, reverse)
|
||||||
return manager_class(instance=self.instance)
|
return manager_class(instance=self.instance)
|
||||||
do_not_call_in_templates = True
|
do_not_call_in_templates = True
|
||||||
|
@ -924,7 +914,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||||
)
|
)
|
||||||
clear.alters_data = True
|
clear.alters_data = True
|
||||||
|
|
||||||
def set(self, objs, **kwargs):
|
def set(self, objs, *, clear=False):
|
||||||
if not rel.through._meta.auto_created:
|
if not rel.through._meta.auto_created:
|
||||||
opts = self.through._meta
|
opts = self.through._meta
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
|
@ -937,8 +927,6 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||||
# could be affected by `manager.clear()`. Refs #19816.
|
# could be affected by `manager.clear()`. Refs #19816.
|
||||||
objs = tuple(objs)
|
objs = tuple(objs)
|
||||||
|
|
||||||
clear = kwargs.pop('clear', False)
|
|
||||||
|
|
||||||
db = router.db_for_write(self.through, instance=self.instance)
|
db = router.db_for_write(self.through, instance=self.instance)
|
||||||
with transaction.atomic(using=db, savepoint=False):
|
with transaction.atomic(using=db, savepoint=False):
|
||||||
if clear:
|
if clear:
|
||||||
|
|
|
@ -165,9 +165,8 @@ class Length(Transform):
|
||||||
function = 'LENGTH'
|
function = 'LENGTH'
|
||||||
lookup_name = 'length'
|
lookup_name = 'length'
|
||||||
|
|
||||||
def __init__(self, expression, **extra):
|
def __init__(self, expression, *, output_field=None, **extra):
|
||||||
output_field = extra.pop('output_field', fields.IntegerField())
|
super().__init__(expression, output_field=output_field or fields.IntegerField(), **extra)
|
||||||
super().__init__(expression, output_field=output_field, **extra)
|
|
||||||
|
|
||||||
def as_mysql(self, compiler, connection):
|
def as_mysql(self, compiler, connection):
|
||||||
return super().as_sql(compiler, connection, function='CHAR_LENGTH')
|
return super().as_sql(compiler, connection, function='CHAR_LENGTH')
|
||||||
|
|
|
@ -691,11 +691,7 @@ class QuerySet:
|
||||||
clone._iterable_class = ValuesIterable
|
clone._iterable_class = ValuesIterable
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def values_list(self, *fields, **kwargs):
|
def values_list(self, *fields, flat=False):
|
||||||
flat = kwargs.pop('flat', False)
|
|
||||||
if kwargs:
|
|
||||||
raise TypeError('Unexpected keyword arguments to values_list: %s' % (list(kwargs),))
|
|
||||||
|
|
||||||
if flat and len(fields) > 1:
|
if flat and len(fields) > 1:
|
||||||
raise TypeError("'flat' is not valid when values_list is called with more than one field.")
|
raise TypeError("'flat' is not valid when values_list is called with more than one field.")
|
||||||
|
|
||||||
|
@ -812,7 +808,7 @@ class QuerySet:
|
||||||
else:
|
else:
|
||||||
return self._filter_or_exclude(None, **filter_obj)
|
return self._filter_or_exclude(None, **filter_obj)
|
||||||
|
|
||||||
def _combinator_query(self, combinator, *other_qs, **kwargs):
|
def _combinator_query(self, combinator, *other_qs, all=False):
|
||||||
# Clone the query to inherit the select list and everything
|
# Clone the query to inherit the select list and everything
|
||||||
clone = self._clone()
|
clone = self._clone()
|
||||||
# Clear limits and ordering so they can be reapplied
|
# Clear limits and ordering so they can be reapplied
|
||||||
|
@ -820,18 +816,11 @@ class QuerySet:
|
||||||
clone.query.clear_limits()
|
clone.query.clear_limits()
|
||||||
clone.query.combined_queries = (self.query,) + tuple(qs.query for qs in other_qs)
|
clone.query.combined_queries = (self.query,) + tuple(qs.query for qs in other_qs)
|
||||||
clone.query.combinator = combinator
|
clone.query.combinator = combinator
|
||||||
clone.query.combinator_all = kwargs.pop('all', False)
|
clone.query.combinator_all = all
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def union(self, *other_qs, **kwargs):
|
def union(self, *other_qs, all=False):
|
||||||
if kwargs:
|
return self._combinator_query('union', *other_qs, all=all)
|
||||||
unexpected_kwarg = next((k for k in kwargs.keys() if k != 'all'), None)
|
|
||||||
if unexpected_kwarg:
|
|
||||||
raise TypeError(
|
|
||||||
"union() received an unexpected keyword argument '%s'" %
|
|
||||||
(unexpected_kwarg,)
|
|
||||||
)
|
|
||||||
return self._combinator_query('union', *other_qs, **kwargs)
|
|
||||||
|
|
||||||
def intersection(self, *other_qs):
|
def intersection(self, *other_qs):
|
||||||
return self._combinator_query('intersection', *other_qs)
|
return self._combinator_query('intersection', *other_qs)
|
||||||
|
|
|
@ -541,9 +541,9 @@ class FileField(Field):
|
||||||
'contradiction': _('Please either submit a file or check the clear checkbox, not both.')
|
'contradiction': _('Please either submit a file or check the clear checkbox, not both.')
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, max_length=None, allow_empty_file=False, **kwargs):
|
||||||
self.max_length = kwargs.pop('max_length', None)
|
self.max_length = max_length
|
||||||
self.allow_empty_file = kwargs.pop('allow_empty_file', False)
|
self.allow_empty_file = allow_empty_file
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_python(self, data):
|
def to_python(self, data):
|
||||||
|
@ -821,9 +821,9 @@ class ChoiceField(Field):
|
||||||
|
|
||||||
|
|
||||||
class TypedChoiceField(ChoiceField):
|
class TypedChoiceField(ChoiceField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, coerce=lambda val: val, empty_value='', **kwargs):
|
||||||
self.coerce = kwargs.pop('coerce', lambda val: val)
|
self.coerce = coerce
|
||||||
self.empty_value = kwargs.pop('empty_value', '')
|
self.empty_value = empty_value
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _coerce(self, value):
|
def _coerce(self, value):
|
||||||
|
@ -890,8 +890,8 @@ class MultipleChoiceField(ChoiceField):
|
||||||
|
|
||||||
|
|
||||||
class TypedMultipleChoiceField(MultipleChoiceField):
|
class TypedMultipleChoiceField(MultipleChoiceField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, coerce=lambda val: val, **kwargs):
|
||||||
self.coerce = kwargs.pop('coerce', lambda val: val)
|
self.coerce = coerce
|
||||||
self.empty_value = kwargs.pop('empty_value', [])
|
self.empty_value = kwargs.pop('empty_value', [])
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -971,8 +971,8 @@ class MultiValueField(Field):
|
||||||
'incomplete': _('Enter a complete value.'),
|
'incomplete': _('Enter a complete value.'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, fields=(), *args, **kwargs):
|
def __init__(self, fields=(), *args, require_all_fields=True, **kwargs):
|
||||||
self.require_all_fields = kwargs.pop('require_all_fields', True)
|
self.require_all_fields = require_all_fields
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
for f in fields:
|
for f in fields:
|
||||||
f.error_messages.setdefault('incomplete',
|
f.error_messages.setdefault('incomplete',
|
||||||
|
@ -1174,8 +1174,8 @@ class GenericIPAddressField(CharField):
|
||||||
class SlugField(CharField):
|
class SlugField(CharField):
|
||||||
default_validators = [validators.validate_slug]
|
default_validators = [validators.validate_slug]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, allow_unicode=False, **kwargs):
|
||||||
self.allow_unicode = kwargs.pop('allow_unicode', False)
|
self.allow_unicode = allow_unicode
|
||||||
if self.allow_unicode:
|
if self.allow_unicode:
|
||||||
self.default_validators = [validators.validate_unicode_slug]
|
self.default_validators = [validators.validate_unicode_slug]
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
|
@ -553,9 +553,9 @@ class BaseModelFormSet(BaseFormSet):
|
||||||
unique_fields = set()
|
unique_fields = set()
|
||||||
|
|
||||||
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
|
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
|
||||||
queryset=None, **kwargs):
|
queryset=None, *, initial=None, **kwargs):
|
||||||
self.queryset = queryset
|
self.queryset = queryset
|
||||||
self.initial_extra = kwargs.pop('initial', None)
|
self.initial_extra = initial
|
||||||
defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
|
defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
super().__init__(**defaults)
|
super().__init__(**defaults)
|
||||||
|
@ -1065,10 +1065,10 @@ class InlineForeignKeyField(Field):
|
||||||
'invalid_choice': _('The inline foreign key did not match the parent instance primary key.'),
|
'invalid_choice': _('The inline foreign key did not match the parent instance primary key.'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, parent_instance, *args, **kwargs):
|
def __init__(self, parent_instance, *args, pk_field=False, to_field=None, **kwargs):
|
||||||
self.parent_instance = parent_instance
|
self.parent_instance = parent_instance
|
||||||
self.pk_field = kwargs.pop("pk_field", False)
|
self.pk_field = pk_field
|
||||||
self.to_field = kwargs.pop("to_field", None)
|
self.to_field = to_field
|
||||||
if self.parent_instance is not None:
|
if self.parent_instance is not None:
|
||||||
if self.to_field:
|
if self.to_field:
|
||||||
kwargs["initial"] = getattr(self.parent_instance, self.to_field)
|
kwargs["initial"] = getattr(self.parent_instance, self.to_field)
|
||||||
|
|
|
@ -30,7 +30,7 @@ def render(request, template_name, context=None, content_type=None, status=None,
|
||||||
return HttpResponse(content, content_type, status)
|
return HttpResponse(content, content_type, status)
|
||||||
|
|
||||||
|
|
||||||
def redirect(to, *args, **kwargs):
|
def redirect(to, *args, permanent=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns an HttpResponseRedirect to the appropriate URL for the arguments
|
Returns an HttpResponseRedirect to the appropriate URL for the arguments
|
||||||
passed.
|
passed.
|
||||||
|
@ -47,11 +47,7 @@ def redirect(to, *args, **kwargs):
|
||||||
By default issues a temporary redirect; pass permanent=True to issue a
|
By default issues a temporary redirect; pass permanent=True to issue a
|
||||||
permanent redirect
|
permanent redirect
|
||||||
"""
|
"""
|
||||||
if kwargs.pop('permanent', False):
|
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
|
||||||
redirect_class = HttpResponsePermanentRedirect
|
|
||||||
else:
|
|
||||||
redirect_class = HttpResponseRedirect
|
|
||||||
|
|
||||||
return redirect_class(resolve_url(to, *args, **kwargs))
|
return redirect_class(resolve_url(to, *args, **kwargs))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -157,10 +157,10 @@ class ExtendsNode(Node):
|
||||||
class IncludeNode(Node):
|
class IncludeNode(Node):
|
||||||
context_key = '__include_context'
|
context_key = '__include_context'
|
||||||
|
|
||||||
def __init__(self, template, *args, **kwargs):
|
def __init__(self, template, *args, extra_context=None, isolated_context=False, **kwargs):
|
||||||
self.template = template
|
self.template = template
|
||||||
self.extra_context = kwargs.pop('extra_context', {})
|
self.extra_context = extra_context or {}
|
||||||
self.isolated_context = kwargs.pop('isolated_context', False)
|
self.isolated_context = isolated_context
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
|
|
@ -929,8 +929,7 @@ class TransactionTestCase(SimpleTestCase):
|
||||||
"against more than one ordered values")
|
"against more than one ordered values")
|
||||||
return self.assertEqual(list(items), values, msg=msg)
|
return self.assertEqual(list(items), values, msg=msg)
|
||||||
|
|
||||||
def assertNumQueries(self, num, func=None, *args, **kwargs):
|
def assertNumQueries(self, num, func=None, *args, using=DEFAULT_DB_ALIAS, **kwargs):
|
||||||
using = kwargs.pop("using", DEFAULT_DB_ALIAS)
|
|
||||||
conn = connections[using]
|
conn = connections[using]
|
||||||
|
|
||||||
context = _AssertNumQueriesContext(self, num, conn)
|
context = _AssertNumQueriesContext(self, num, conn)
|
||||||
|
|
|
@ -235,12 +235,7 @@ class ImmutableList(tuple):
|
||||||
AttributeError: You cannot mutate this.
|
AttributeError: You cannot mutate this.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, warning='ImmutableList object is immutable.', **kwargs):
|
||||||
if 'warning' in kwargs:
|
|
||||||
warning = kwargs['warning']
|
|
||||||
del kwargs['warning']
|
|
||||||
else:
|
|
||||||
warning = 'ImmutableList object is immutable.'
|
|
||||||
self = tuple.__new__(cls, *args, **kwargs)
|
self = tuple.__new__(cls, *args, **kwargs)
|
||||||
self.warning = warning
|
self.warning = warning
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -3,15 +3,13 @@ from importlib import import_module
|
||||||
from django.utils.version import get_docs_version
|
from django.utils.version import get_docs_version
|
||||||
|
|
||||||
|
|
||||||
def deconstructible(*args, **kwargs):
|
def deconstructible(*args, path=None):
|
||||||
"""
|
"""
|
||||||
Class decorator that allow the decorated class to be serialized
|
Class decorator that allow the decorated class to be serialized
|
||||||
by the migrations subsystem.
|
by the migrations subsystem.
|
||||||
|
|
||||||
Accepts an optional kwarg `path` to specify the import path.
|
Accepts an optional kwarg `path` to specify the import path.
|
||||||
"""
|
"""
|
||||||
path = kwargs.pop('path', None)
|
|
||||||
|
|
||||||
def decorator(klass):
|
def decorator(klass):
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
# We capture the arguments to make returning them trivial
|
# We capture the arguments to make returning them trivial
|
||||||
|
@ -54,4 +52,4 @@ def deconstructible(*args, **kwargs):
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
return decorator
|
return decorator
|
||||||
return decorator(*args, **kwargs)
|
return decorator(*args)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.utils.cache import add_never_cache_headers, patch_cache_control
|
||||||
from django.utils.decorators import decorator_from_middleware_with_args
|
from django.utils.decorators import decorator_from_middleware_with_args
|
||||||
|
|
||||||
|
|
||||||
def cache_page(*args, **kwargs):
|
def cache_page(timeout, *, cache=None, key_prefix=None):
|
||||||
"""
|
"""
|
||||||
Decorator for views that tries getting the page from the cache and
|
Decorator for views that tries getting the page from the cache and
|
||||||
populates the cache if the page isn't in the cache yet.
|
populates the cache if the page isn't in the cache yet.
|
||||||
|
@ -19,18 +19,8 @@ def cache_page(*args, **kwargs):
|
||||||
Additionally, all headers from the response's Vary header will be taken
|
Additionally, all headers from the response's Vary header will be taken
|
||||||
into account on caching -- just like the middleware does.
|
into account on caching -- just like the middleware does.
|
||||||
"""
|
"""
|
||||||
# We also add some asserts to give better error messages in case people are
|
|
||||||
# using other ways to call cache_page that no longer work.
|
|
||||||
if len(args) != 1 or callable(args[0]):
|
|
||||||
raise TypeError("cache_page has a single mandatory positional argument: timeout")
|
|
||||||
cache_timeout = args[0]
|
|
||||||
cache_alias = kwargs.pop('cache', None)
|
|
||||||
key_prefix = kwargs.pop('key_prefix', None)
|
|
||||||
if kwargs:
|
|
||||||
raise TypeError("cache_page has two optional keyword arguments: cache and key_prefix")
|
|
||||||
|
|
||||||
return decorator_from_middleware_with_args(CacheMiddleware)(
|
return decorator_from_middleware_with_args(CacheMiddleware)(
|
||||||
cache_timeout=cache_timeout, cache_alias=cache_alias, key_prefix=key_prefix
|
cache_timeout=timeout, cache_alias=cache, key_prefix=key_prefix
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,11 +120,11 @@ class MultipleObjectMixin(ContextMixin):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, *, object_list=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Get the context for this view.
|
Get the context for this view.
|
||||||
"""
|
"""
|
||||||
queryset = kwargs.pop('object_list', self.object_list)
|
queryset = object_list if object_list is not None else self.object_list
|
||||||
page_size = self.get_paginate_by(queryset)
|
page_size = self.get_paginate_by(queryset)
|
||||||
context_object_name = self.get_context_object_name(queryset)
|
context_object_name = self.get_context_object_name(queryset)
|
||||||
if page_size:
|
if page_size:
|
||||||
|
|
|
@ -557,8 +557,8 @@ You can pass this parameter when instantiating the formset::
|
||||||
>>> from myapp.forms import ArticleForm
|
>>> from myapp.forms import ArticleForm
|
||||||
|
|
||||||
>>> class MyArticleForm(ArticleForm):
|
>>> class MyArticleForm(ArticleForm):
|
||||||
... def __init__(self, *args, **kwargs):
|
... def __init__(self, *args, user, **kwargs):
|
||||||
... self.user = kwargs.pop('user')
|
... self.user = user
|
||||||
... super().__init__(*args, **kwargs)
|
... super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
>>> ArticleFormSet = formset_factory(MyArticleForm)
|
>>> ArticleFormSet = formset_factory(MyArticleForm)
|
||||||
|
|
|
@ -13,12 +13,10 @@ class RevisionableModel(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s, %s)" % (self.title, self.id, self.base.id)
|
return "%s (%s, %s)" % (self.title, self.id, self.base.id)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, force_insert=None, force_update=None, **kwargs):
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, force_insert=force_insert, force_update=force_update, **kwargs)
|
||||||
if not self.base:
|
if not self.base:
|
||||||
self.base = self
|
self.base = self
|
||||||
kwargs.pop('force_insert', None)
|
|
||||||
kwargs.pop('force_update', None)
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def new_revision(self):
|
def new_revision(self):
|
||||||
|
|
|
@ -56,8 +56,8 @@ SplitDateTimeFormSet = formset_factory(SplitDateTimeForm)
|
||||||
|
|
||||||
|
|
||||||
class CustomKwargForm(Form):
|
class CustomKwargForm(Form):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, custom_kwarg, **kwargs):
|
||||||
self.custom_kwarg = kwargs.pop('custom_kwarg')
|
self.custom_kwarg = custom_kwarg
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1258,8 +1258,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
|
||||||
to the parent class during `__init__`.
|
to the parent class during `__init__`.
|
||||||
"""
|
"""
|
||||||
class ExtendedPolygon(Polygon):
|
class ExtendedPolygon(Polygon):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, data=0, **kwargs):
|
||||||
data = kwargs.pop('data', 0)
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._data = data
|
self._data = data
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,8 @@ class TestDS(TestObj):
|
||||||
"""
|
"""
|
||||||
Object for testing GDAL data sources.
|
Object for testing GDAL data sources.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, **kwargs):
|
def __init__(self, name, *, ext='shp', **kwargs):
|
||||||
# Shapefile is default extension, unless specified otherwise.
|
# Shapefile is default extension, unless specified otherwise.
|
||||||
ext = kwargs.pop('ext', 'shp')
|
|
||||||
self.ds = get_ds_file(name, ext)
|
self.ds = get_ds_file(name, ext)
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
@ -55,19 +54,14 @@ class TestGeom(TestObj):
|
||||||
Testing object used for wrapping reference geometry data
|
Testing object used for wrapping reference geometry data
|
||||||
in GEOS/GDAL tests.
|
in GEOS/GDAL tests.
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, *, coords=None, centroid=None, ext_ring_cs=None, **kwargs):
|
||||||
# Converting lists to tuples of certain keyword args
|
# Converting lists to tuples of certain keyword args
|
||||||
# so coordinate test cases will match (JSON has no
|
# so coordinate test cases will match (JSON has no
|
||||||
# concept of tuple).
|
# concept of tuple).
|
||||||
coords = kwargs.pop('coords', None)
|
|
||||||
if coords:
|
if coords:
|
||||||
self.coords = tuplize(coords)
|
self.coords = tuplize(coords)
|
||||||
|
|
||||||
centroid = kwargs.pop('centroid', None)
|
|
||||||
if centroid:
|
if centroid:
|
||||||
self.centroid = tuple(centroid)
|
self.centroid = tuple(centroid)
|
||||||
|
|
||||||
ext_ring_cs = kwargs.pop('ext_ring_cs', None)
|
|
||||||
if ext_ring_cs:
|
if ext_ring_cs:
|
||||||
ext_ring_cs = tuplize(ext_ring_cs)
|
ext_ring_cs = tuplize(ext_ring_cs)
|
||||||
self.ext_ring_cs = ext_ring_cs
|
self.ext_ring_cs = ext_ring_cs
|
||||||
|
|
|
@ -1388,10 +1388,6 @@ class UnprefixedDefaultLanguageTests(SimpleTestCase):
|
||||||
response = self.client.get('/simple/', HTTP_ACCEPT_LANGUAGE='fr')
|
response = self.client.get('/simple/', HTTP_ACCEPT_LANGUAGE='fr')
|
||||||
self.assertEqual(response.content, b'Yes')
|
self.assertEqual(response.content, b'Yes')
|
||||||
|
|
||||||
def test_unexpected_kwarg_to_i18n_patterns(self):
|
|
||||||
with self.assertRaisesMessage(AssertionError, "Unexpected kwargs for i18n_patterns(): {'foo':"):
|
|
||||||
i18n_patterns(object(), foo='bar')
|
|
||||||
|
|
||||||
def test_page_with_dash(self):
|
def test_page_with_dash(self):
|
||||||
# A page starting with /de* shouldn't match the 'de' langauge code.
|
# A page starting with /de* shouldn't match the 'de' langauge code.
|
||||||
response = self.client.get('/de-simple-page/')
|
response = self.client.get('/de-simple-page/')
|
||||||
|
|
|
@ -13,19 +13,19 @@ class SecurityMiddlewareTest(SimpleTestCase):
|
||||||
def secure_request_kwargs(self):
|
def secure_request_kwargs(self):
|
||||||
return {"wsgi.url_scheme": "https"}
|
return {"wsgi.url_scheme": "https"}
|
||||||
|
|
||||||
def response(self, *args, **kwargs):
|
def response(self, *args, headers=None, **kwargs):
|
||||||
headers = kwargs.pop("headers", {})
|
|
||||||
response = HttpResponse(*args, **kwargs)
|
response = HttpResponse(*args, **kwargs)
|
||||||
for k, v in headers.items():
|
if headers:
|
||||||
response[k] = v
|
for k, v in headers.items():
|
||||||
|
response[k] = v
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def process_response(self, *args, **kwargs):
|
def process_response(self, *args, secure=False, request=None, **kwargs):
|
||||||
request_kwargs = {}
|
request_kwargs = {}
|
||||||
if kwargs.pop("secure", False):
|
if secure:
|
||||||
request_kwargs.update(self.secure_request_kwargs)
|
request_kwargs.update(self.secure_request_kwargs)
|
||||||
request = (kwargs.pop("request", None) or
|
if request is None:
|
||||||
self.request.get("/some/url", **request_kwargs))
|
request = self.request.get("/some/url", **request_kwargs)
|
||||||
ret = self.middleware.process_request(request)
|
ret = self.middleware.process_request(request)
|
||||||
if ret:
|
if ret:
|
||||||
return ret
|
return ret
|
||||||
|
@ -34,8 +34,8 @@ class SecurityMiddlewareTest(SimpleTestCase):
|
||||||
|
|
||||||
request = RequestFactory()
|
request = RequestFactory()
|
||||||
|
|
||||||
def process_request(self, method, *args, **kwargs):
|
def process_request(self, method, *args, secure=False, **kwargs):
|
||||||
if kwargs.pop("secure", False):
|
if secure:
|
||||||
kwargs.update(self.secure_request_kwargs)
|
kwargs.update(self.secure_request_kwargs)
|
||||||
req = getattr(self.request, method.lower())(*args, **kwargs)
|
req = getattr(self.request, method.lower())(*args, **kwargs)
|
||||||
return self.middleware.process_request(req)
|
return self.middleware.process_request(req)
|
||||||
|
|
|
@ -40,12 +40,10 @@ class Person(models.Model):
|
||||||
# calls. This argument is used to establish that the BookManager
|
# calls. This argument is used to establish that the BookManager
|
||||||
# is actually getting used when it should be.
|
# is actually getting used when it should be.
|
||||||
class BookManager(models.Manager):
|
class BookManager(models.Manager):
|
||||||
def create(self, *args, **kwargs):
|
def create(self, *args, extra_arg=None, **kwargs):
|
||||||
kwargs.pop('extra_arg', None)
|
|
||||||
return super().create(*args, **kwargs)
|
return super().create(*args, **kwargs)
|
||||||
|
|
||||||
def get_or_create(self, *args, **kwargs):
|
def get_or_create(self, *args, extra_arg=None, **kwargs):
|
||||||
kwargs.pop('extra_arg', None)
|
|
||||||
return super().get_or_create(*args, **kwargs)
|
return super().get_or_create(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,6 @@ class QuerySetSetOperationTests(TestCase):
|
||||||
self.assertEqual(len(list(qs1.union(qs2, all=True))), 20)
|
self.assertEqual(len(list(qs1.union(qs2, all=True))), 20)
|
||||||
self.assertEqual(len(list(qs1.union(qs2))), 10)
|
self.assertEqual(len(list(qs1.union(qs2))), 10)
|
||||||
|
|
||||||
def test_union_bad_kwarg(self):
|
|
||||||
qs1 = Number.objects.all()
|
|
||||||
msg = "union() received an unexpected keyword argument 'bad'"
|
|
||||||
with self.assertRaisesMessage(TypeError, msg):
|
|
||||||
self.assertEqual(len(list(qs1.union(qs1, bad=True))), 20)
|
|
||||||
|
|
||||||
def test_limits(self):
|
def test_limits(self):
|
||||||
qs1 = Number.objects.all()
|
qs1 = Number.objects.all()
|
||||||
qs2 = Number.objects.all()
|
qs2 = Number.objects.all()
|
||||||
|
|
|
@ -13,23 +13,24 @@ class CustomManyToManyField(RelatedField):
|
||||||
"""
|
"""
|
||||||
many_to_many = True
|
many_to_many = True
|
||||||
|
|
||||||
def __init__(self, to, db_constraint=True, swappable=True, **kwargs):
|
def __init__(self, to, db_constraint=True, swappable=True, related_name=None, related_query_name=None,
|
||||||
|
limit_choices_to=None, symmetrical=None, through=None, through_fields=None, db_table=None, **kwargs):
|
||||||
try:
|
try:
|
||||||
to._meta
|
to._meta
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
to = str(to)
|
to = str(to)
|
||||||
kwargs['rel'] = ManyToManyRel(
|
kwargs['rel'] = ManyToManyRel(
|
||||||
self, to,
|
self, to,
|
||||||
related_name=kwargs.pop('related_name', None),
|
related_name=related_name,
|
||||||
related_query_name=kwargs.pop('related_query_name', None),
|
related_query_name=related_query_name,
|
||||||
limit_choices_to=kwargs.pop('limit_choices_to', None),
|
limit_choices_to=limit_choices_to,
|
||||||
symmetrical=kwargs.pop('symmetrical', to == RECURSIVE_RELATIONSHIP_CONSTANT),
|
symmetrical=symmetrical if symmetrical is not None else (to == RECURSIVE_RELATIONSHIP_CONSTANT),
|
||||||
through=kwargs.pop('through', None),
|
through=through,
|
||||||
through_fields=kwargs.pop('through_fields', None),
|
through_fields=through_fields,
|
||||||
db_constraint=db_constraint,
|
db_constraint=db_constraint,
|
||||||
)
|
)
|
||||||
self.swappable = swappable
|
self.swappable = swappable
|
||||||
self.db_table = kwargs.pop('db_table', None)
|
self.db_table = db_table
|
||||||
if kwargs['rel'].through is not None:
|
if kwargs['rel'].through is not None:
|
||||||
assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
|
assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
|
@ -1819,9 +1819,9 @@ class SchemaTests(TransactionTestCase):
|
||||||
"""
|
"""
|
||||||
#23065 - Constraint names must be quoted if they contain capital letters.
|
#23065 - Constraint names must be quoted if they contain capital letters.
|
||||||
"""
|
"""
|
||||||
def get_field(*args, **kwargs):
|
def get_field(*args, field_class=IntegerField, **kwargs):
|
||||||
kwargs['db_column'] = "CamelCase"
|
kwargs['db_column'] = "CamelCase"
|
||||||
field = kwargs.pop('field_class', IntegerField)(*args, **kwargs)
|
field = field_class(*args, **kwargs)
|
||||||
field.set_attributes_from_name("CamelCase")
|
field.set_attributes_from_name("CamelCase")
|
||||||
return field
|
return field
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,7 @@ class CollectionTestCase(BaseStaticFilesMixin, SimpleTestCase):
|
||||||
self.patched_settings.disable()
|
self.patched_settings.disable()
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
def run_collectstatic(self, **kwargs):
|
def run_collectstatic(self, *, verbosity=0, **kwargs):
|
||||||
verbosity = kwargs.pop('verbosity', 0)
|
|
||||||
call_command('collectstatic', interactive=False, verbosity=verbosity,
|
call_command('collectstatic', interactive=False, verbosity=verbosity,
|
||||||
ignore_patterns=['*.ignoreme'], **kwargs)
|
ignore_patterns=['*.ignoreme'], **kwargs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue