diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py
index f48e683074..4896dc75b8 100644
--- a/InvenTree/InvenTree/forms.py
+++ b/InvenTree/InvenTree/forms.py
@@ -67,10 +67,10 @@ class HelperForm(forms.ModelForm):
# Look for font-awesome icons
if prefix and prefix.startswith('fa-'):
- prefix = r"".format(fa=prefix)
+ prefix = f""
if suffix and suffix.startswith('fa-'):
- suffix = r"".format(fa=suffix)
+ suffix = f""
if prefix and suffix:
layouts.append(
diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py
index a59b9fe26a..facb8b3bf7 100644
--- a/InvenTree/InvenTree/helpers.py
+++ b/InvenTree/InvenTree/helpers.py
@@ -520,7 +520,7 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
if a == b:
# Invalid group
- add_error(_("Invalid group range: {g}").format(g=group))
+ add_error(_(f"Invalid group range: {group}"))
continue
group_items = []
@@ -549,13 +549,13 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
break
if len(group_items) > remaining:
- add_error(_("Group range {g} exceeds allowed quantity ({q})".format(g=group, q=expected_quantity)))
+ add_error(_(f"Group range {group} exceeds allowed quantity ({expected_quantity})"))
elif len(group_items) > 0 and group_items[0] == a and group_items[-1] == b:
# In this case, the range extraction looks like it has worked
for item in group_items:
add_serial(item)
else:
- add_error(_("Invalid group range: {g}").format(g=group))
+ add_error(_(f"Invalid group range: {group}"))
else:
# In the case of a different number of hyphens, simply add the entire group
@@ -573,14 +573,14 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
sequence_count = max(0, expected_quantity - len(serials))
if len(items) > 2 or len(items) == 0:
- add_error(_("Invalid group sequence: {g}").format(g=group))
+ add_error(_(f"Invalid group sequence: {group}"))
continue
elif len(items) == 2:
try:
if items[1]:
sequence_count = int(items[1]) + 1
except ValueError:
- add_error(_("Invalid group sequence: {g}").format(g=group))
+ add_error(_(f"Invalid group sequence: {group}"))
continue
value = items[0]
@@ -595,7 +595,7 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
for item in sequence_items:
add_serial(item)
else:
- add_error(_("Invalid group sequence: {g}").format(g=group))
+ add_error(_(f"Invalid group sequence: {group}"))
else:
# At this point, we assume that the 'group' is just a single serial value
@@ -608,7 +608,7 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
raise ValidationError([_("No serial numbers found")])
if len(errors) == 0 and len(serials) != expected_quantity:
- raise ValidationError([_("Number of unique serial numbers ({s}) must match quantity ({q})").format(s=len(serials), q=expected_quantity)])
+ raise ValidationError([_(f"Number of unique serial numbers ({len(serials)}) must match quantity ({expected_quantity})")])
return serials
@@ -646,7 +646,7 @@ def validateFilterString(value, model=None):
if len(pair) != 2:
raise ValidationError(
- "Invalid group: {g}".format(g=group)
+ f"Invalid group: {group}"
)
k, v = pair
@@ -656,7 +656,7 @@ def validateFilterString(value, model=None):
if not k or not v:
raise ValidationError(
- "Invalid group: {g}".format(g=group)
+ f"Invalid group: {group}"
)
results[k] = v
diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py
index 4e939a9da1..15910552dd 100644
--- a/InvenTree/InvenTree/models.py
+++ b/InvenTree/InvenTree/models.py
@@ -762,7 +762,7 @@ class InvenTreeTree(MPTTModel):
def __str__(self):
"""String representation of a category is the full path to that category."""
- return "{path} - {desc}".format(path=self.pathstring, desc=self.description)
+ return f"{self.pathstring} - {self.description}"
class InvenTreeNotesMixin(models.Model):
diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py
index 4947f6fb63..f5eef23b3a 100644
--- a/InvenTree/company/models.py
+++ b/InvenTree/company/models.py
@@ -50,7 +50,7 @@ def rename_company_image(instance, filename):
else:
ext = ''
- fn = 'company_{pk}_img'.format(pk=instance.pk)
+ fn = f'company_{instance.pk}_img'
if ext:
fn += '.' + ext
@@ -185,7 +185,7 @@ class Company(InvenTreeNotesMixin, MetadataMixin, models.Model):
def __str__(self):
"""Get string representation of a Company."""
- return "{n} - {d}".format(n=self.name, d=self.description)
+ return f"{self.name} - {self.description}"
def get_absolute_url(self):
"""Get the web URL for the detail view for this Company."""
diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py
index 18cc2e843f..3b33f86e9a 100644
--- a/InvenTree/label/models.py
+++ b/InvenTree/label/models.py
@@ -25,7 +25,7 @@ from plugin.registry import registry
try:
from django_weasyprint import WeasyTemplateResponseMixin
except OSError as err: # pragma: no cover
- print("OSError: {e}".format(e=err))
+ print(f"OSError: {err}")
print("You may require some further system packages to be installed.")
sys.exit(1)
@@ -109,10 +109,7 @@ class LabelTemplate(MetadataMixin, models.Model):
def __str__(self):
"""Format a string representation of a label instance"""
- return "{n} - {d}".format(
- n=self.name,
- d=self.description
- )
+ return f"{self.name} - {self.description}"
name = models.CharField(
blank=False, max_length=100,
diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py
index 3d319a8d28..8895c134ba 100644
--- a/InvenTree/order/views.py
+++ b/InvenTree/order/views.py
@@ -306,11 +306,7 @@ class PurchaseOrderExport(AjaxView):
export_format = request.GET.get('format', 'csv')
- filename = '{order} - {company}.{fmt}'.format(
- order=str(order),
- company=order.supplier.name,
- fmt=export_format
- )
+ filename = f'{str(order)} - {order.supplier.name}.{export_format}'
dataset = PurchaseOrderLineItemResource().export(queryset=order.lines.all())
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 2960d8335b..b39196645c 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -518,10 +518,7 @@ class Part(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, MPTTModel)
try:
if self.pk == parent.pk:
- raise ValidationError({'sub_part': _("Part '{p1}' is used in BOM for '{p2}' (recursive)").format(
- p1=str(self),
- p2=str(parent)
- )})
+ raise ValidationError({'sub_part': _(f"Part '{self}' is used in BOM for '{parent}' (recursive)")})
bom_items = self.get_bom_items()
@@ -530,10 +527,7 @@ class Part(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, MPTTModel)
# Check for simple match
if item.sub_part == parent:
- raise ValidationError({'sub_part': _("Part '{p1}' is used in BOM for '{p2}' (recursive)").format(
- p1=str(parent),
- p2=str(self)
- )})
+ raise ValidationError({'sub_part': _(f"Part '{parent}' is used in BOM for '{self}' (recursive)")})
# And recursively check too
if recursive:
@@ -600,7 +594,7 @@ class Part(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, MPTTModel)
match = re.search(pattern, self.IPN)
if match is None:
- raise ValidationError(_('IPN must match regex pattern {pat}').format(pat=pattern))
+ raise ValidationError(_(f'IPN must match regex pattern {pattern}'))
def validate_serial_number(self, serial: str, stock_item=None, check_duplicates=True, raise_error=False, **kwargs):
"""Validate a serial number against this Part instance.
@@ -1799,7 +1793,7 @@ class Part(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, MPTTModel)
min_price = normalize(min_price)
max_price = normalize(max_price)
- return "{a} - {b}".format(a=min_price, b=max_price)
+ return f"{min_price} - {max_price}"
def get_supplier_price_range(self, quantity=1):
"""Return the supplier price range of this part:
@@ -3358,7 +3352,7 @@ class PartParameterTemplate(MetadataMixin, models.Model):
"""Return a string representation of a PartParameterTemplate instance"""
s = str(self.name)
if self.units:
- s += " ({units})".format(units=self.units)
+ s += f" ({self.units})"
return s
def clean(self):
@@ -3498,12 +3492,7 @@ class PartParameter(MetadataMixin, models.Model):
def __str__(self):
"""String representation of a PartParameter (used in the admin interface)"""
- return "{part} : {param} = {data} ({units})".format(
- part=str(self.part.full_name),
- param=str(self.template.name),
- data=str(self.data),
- units=str(self.template.units)
- )
+ return f"{self.part.full_name} : {self.template.name} = {self.data} ({self.template.units})"
def save(self, *args, **kwargs):
"""Custom save method for the PartParameter model."""
@@ -3726,10 +3715,7 @@ class BomItem(DataImportMixin, MetadataMixin, models.Model):
def __str__(self):
"""Return a string representation of this BomItem instance"""
- return "{n} x {child} to make {parent}".format(
- parent=self.part.full_name,
- child=self.sub_part.full_name,
- n=decimal2string(self.quantity))
+ return f"{decimal2string(self.quantity)} x {self.sub_part.full_name} to make {self.part.full_name}"
@staticmethod
def get_api_url():
@@ -4043,7 +4029,7 @@ class BomItem(DataImportMixin, MetadataMixin, models.Model):
pmin = decimal2money(pmin)
pmax = decimal2money(pmax)
- return "{pmin} to {pmax}".format(pmin=pmin, pmax=pmax)
+ return f"{pmin} to {pmax}"
@receiver(post_save, sender=BomItem, dispatch_uid='update_bom_build_lines')
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
index e5a8fafb32..753a63dc34 100644
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -235,10 +235,7 @@ def python_version(*args, **kwargs):
def inventree_version(shortstring=False, *args, **kwargs):
"""Return InvenTree version string."""
if shortstring:
- return _("{title} v{version}".format(
- title=version.inventreeInstanceTitle(),
- version=version.inventreeVersion()
- ))
+ return _(f"{version.inventreeInstanceTitle()} v{version.inventreeVersion()}")
return version.inventreeVersion()
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index d236dfbe62..f67bc35bc2 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -239,7 +239,7 @@ class PartImport(FileManagementFormView):
# check if there's a category assigned, if not skip this part or else bad things happen
if not optional_matches['Category']:
- import_error.append(_("Can't import part {name} because there is no category assigned").format(name=new_part.name))
+ import_error.append(_(f"Can't import part {new_part.name} because there is no category assigned"))
continue
try:
@@ -260,7 +260,7 @@ class PartImport(FileManagementFormView):
# Set alerts
if import_done:
- alert = f"{_('Part-Import')}
{_('Imported {n} parts').format(n=import_done)}"
+ alert = f"{_('Part-Import')}
{_(f'Imported {import_done} parts')}"
messages.success(self.request, alert)
if import_error:
error_text = '\n'.join([f'