diff --git a/rest_framework/filters.py b/rest_framework/filters.py index e68726499..418993405 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -297,7 +297,7 @@ class OrderingFilter(BaseFilterBackend): ascending_translation = _("ascending") descending_translation = _("descending") options.append((key, f'{label} - {ascending_translation}')) - options.append(('-' + key, f'{label} - {descending_translation}')) + options.append((f'-{key}', f'{label} - {descending_translation}')) context['options'] = options return context diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index e815d8d5c..13a91d753 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -118,7 +118,7 @@ def _reverse_ordering(ordering_tuple): ordering and return a new tuple, eg. `('created', '-uuid')`. """ def invert(x): - return x[1:] if x.startswith('-') else '-' + x + return x[1:] if x.startswith('-') else f'-{x}' return tuple([invert(item) for item in ordering_tuple]) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index e8740d57b..068d109c4 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -344,7 +344,7 @@ class HTMLFormRenderer(BaseRenderer): if 'template' in style: template_name = style['template'] else: - template_name = style['template_pack'].strip('/') + '/' + style['base_template'] + template_name = style['template_pack'].strip('/') + f"/{style['base_template']}" template = loader.get_template(template_name) context = {'field': field, 'style': style} diff --git a/rest_framework/routers.py b/rest_framework/routers.py index e0ae24b95..2ee4b457f 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -254,7 +254,7 @@ class SimpleRouter(BaseRouter): # so a slash in the beginning will (A) cause Django to give # warnings and (B) generate URLS that will require using '//'. if not prefix and regex[:2] == '^/': - regex = '^' + regex[2:] + regex = f'^{regex[2:]}' initkwargs = route.initkwargs.copy() initkwargs.update({ @@ -283,7 +283,7 @@ class APIRootView(views.APIView): namespace = request.resolver_match.namespace for key, url_name in self.api_root_dict.items(): if namespace: - url_name = namespace + ':' + url_name + url_name = f"{namespace}:{url_name}" try: ret[key] = reverse( url_name, diff --git a/rest_framework/schemas/coreapi.py b/rest_framework/schemas/coreapi.py index 179f0fa3c..c892caae2 100644 --- a/rest_framework/schemas/coreapi.py +++ b/rest_framework/schemas/coreapi.py @@ -240,7 +240,7 @@ class SchemaGenerator(BaseSchemaGenerator): # We can just break early in the case that there's at least # one URL that doesn't have a path prefix. return '/' - prefixes.append('/' + prefix + '/') + prefixes.append(f'/{prefix}/') return common_path(prefixes) # View Inspectors # diff --git a/rest_framework/schemas/inspectors.py b/rest_framework/schemas/inspectors.py index 027472db1..94f34637d 100644 --- a/rest_framework/schemas/inspectors.py +++ b/rest_framework/schemas/inspectors.py @@ -97,7 +97,7 @@ class ViewInspector: current_section, separator, lead = line.partition(':') sections[current_section] = lead.strip() else: - sections[current_section] += '\n' + line + sections[current_section] += f'\n{line}' # TODO: SCHEMA_COERCE_METHOD_NAMES appears here and in `SchemaGenerator.get_keys` coerce_method_names = api_settings.SCHEMA_COERCE_METHOD_NAMES diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index ac4b92ca8..9d02151fe 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -477,7 +477,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass): fields = self._writable_fields for field in fields: - validate_method = getattr(self, 'validate_' + field.field_name, None) + validate_method = getattr(self, f'validate_{field.field_name}', None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 8e35fec6e..c692eca65 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -187,12 +187,9 @@ def add_class(value, css_class): html = str(value) match = class_re.search(html) if match: - m = re.search(r'^%s$|^%s\s|\s%s\s|\s%s$' % (css_class, css_class, - css_class, css_class), - match.group(1)) + m = re.search(fr'[^|\s]{css_class}[$|\s]', match.group(1)) if not m: - return mark_safe(class_re.sub(match.group(1) + " " + css_class, - html)) + return mark_safe(class_re.sub(f"{match.group(1)} {css_class}", html)) else: return mark_safe(html.replace('>', f' class="{css_class}">', 1)) return value @@ -318,5 +315,5 @@ def break_long_headers(header): when possible (are comma separated) """ if len(header) > 160 and ',' in header: - header = mark_safe('
' + ',
'.join(header.split(','))) + header = mark_safe(f"
{header.replace(',', ',
')}") return header diff --git a/rest_framework/test.py b/rest_framework/test.py index 0212348ee..d9f93b4c7 100644 --- a/rest_framework/test.py +++ b/rest_framework/test.py @@ -171,7 +171,7 @@ class APIRequestFactory(DjangoRequestFactory): "Set TEST_REQUEST_RENDERER_CLASSES to enable " "extra request formats.".format( format, - ', '.join(["'" + fmt + "'" for fmt in self.renderer_classes]) + ', '.join([f"'{fmt}'" for fmt in self.renderer_classes]) ) ) diff --git a/rest_framework/urlpatterns.py b/rest_framework/urlpatterns.py index df2afbe51..e4b4aedcb 100644 --- a/rest_framework/urlpatterns.py +++ b/rest_framework/urlpatterns.py @@ -11,7 +11,7 @@ def _get_format_path_converter(suffix_kwarg, allowed): else: allowed_cases = "|".join(allowed) allowed_pattern = f'(?:{allowed_cases})' - suffix_pattern = r"\.%s/?" % allowed_pattern + suffix_pattern = fr"\.{allowed_pattern}/?" else: suffix_pattern = r"\.[a-z0-9]+/?" @@ -22,7 +22,7 @@ def _get_format_path_converter(suffix_kwarg, allowed): return value.strip('./') def to_url(self, value): - return '.' + value + '/' + return f'.{value}/' converter_name = 'drf_format_suffix' if allowed: @@ -102,9 +102,9 @@ def format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None): else: allowed_cases = "|".join(allowed) allowed_pattern = f'({allowed_cases})' - suffix_pattern = r'\.(?P<%s>%s)/?$' % (suffix_kwarg, allowed_pattern) + suffix_pattern = fr'\.(?P<{suffix_kwarg}>{allowed_pattern})/?$' else: - suffix_pattern = r'\.(?P<%s>[a-z0-9]+)/?$' % suffix_kwarg + suffix_pattern = fr'\.(?P<{suffix_kwarg}>[a-z0-9]+)/?$' converter_name, suffix_converter = _get_format_path_converter(suffix_kwarg, allowed) register_converter(suffix_converter, converter_name) diff --git a/rest_framework/utils/formatting.py b/rest_framework/utils/formatting.py index c5917fd41..5d6604721 100644 --- a/rest_framework/utils/formatting.py +++ b/rest_framework/utils/formatting.py @@ -63,7 +63,7 @@ def markup_description(description): description = apply_markdown(description) else: description = escape(description).replace('\n', '
') - description = '

' + description + '

' + description = f'

{description}

' return mark_safe(description) diff --git a/rest_framework/utils/html.py b/rest_framework/utils/html.py index c7ede7803..d10dbcf8e 100644 --- a/rest_framework/utils/html.py +++ b/rest_framework/utils/html.py @@ -83,7 +83,7 @@ def parse_html_dict(dictionary, prefix=''): } """ ret = MultiValueDict() - regex = re.compile(r'^%s\.(.+)$' % re.escape(prefix)) + regex = re.compile(fr'^{re.escape(prefix)}\.(.+)$') for field in dictionary: match = regex.match(field) if not match: diff --git a/rest_framework/utils/representation.py b/rest_framework/utils/representation.py index f50b601f3..4ba6ae83c 100644 --- a/rest_framework/utils/representation.py +++ b/rest_framework/utils/representation.py @@ -77,7 +77,7 @@ def serializer_repr(serializer, indent, force_many=None): fields = serializer.fields for field_name, field in fields.items(): - ret += '\n' + indent_str + field_name + ' = ' + ret += f'\n{indent_str}{field_name} = ' if hasattr(field, 'fields'): ret += serializer_repr(field, indent + 1) elif hasattr(field, 'child'): diff --git a/rest_framework/versioning.py b/rest_framework/versioning.py index 78cfc9dc8..72c34f624 100644 --- a/rest_framework/versioning.py +++ b/rest_framework/versioning.py @@ -135,7 +135,7 @@ class NamespaceVersioning(BaseVersioning): ) def get_versioned_viewname(self, viewname, request): - return request.version + ':' + viewname + return f"{request.version}:{viewname}" class HostNameVersioning(BaseVersioning): diff --git a/rest_framework/views.py b/rest_framework/views.py index 0b00d2134..c76e4f20d 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -39,7 +39,7 @@ def get_view_name(view): # Suffix may be set by some Views, such as a ViewSet. suffix = getattr(view, 'suffix', None) if suffix: - name += ' ' + suffix + name += f' {suffix}' return name diff --git a/rest_framework/viewsets.py b/rest_framework/viewsets.py index d3988cbcc..926577f41 100644 --- a/rest_framework/viewsets.py +++ b/rest_framework/viewsets.py @@ -162,7 +162,7 @@ class ViewSetMixin: if self.request and self.request.resolver_match: namespace = self.request.resolver_match.namespace if namespace: - url_name = namespace + ':' + url_name + url_name = f"{namespace}:{url_name}" kwargs.setdefault('request', self.request) return reverse(url_name, *args, **kwargs)