mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 04:56:45 +00:00
Add a 'reference_int' field to the models, to be used as a secondary index
This commit is contained in:
parent
e46875b0a3
commit
7ce0f817aa
@ -4,6 +4,7 @@ Generic models which provide extra functionality over base Django model types.
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -43,6 +44,48 @@ def rename_attachment(instance, filename):
|
|||||||
return os.path.join(instance.getSubdir(), filename)
|
return os.path.join(instance.getSubdir(), filename)
|
||||||
|
|
||||||
|
|
||||||
|
class ReferenceIndexingMixin(models.Model):
|
||||||
|
"""
|
||||||
|
A mixin for keeping track of numerical copies of the "reference" field.
|
||||||
|
|
||||||
|
Here, we attempt to convert a "reference" field value (char) to an integer,
|
||||||
|
for performing fast natural sorting.
|
||||||
|
|
||||||
|
This requires extra database space (due to the extra table column),
|
||||||
|
but is required as not all supported database backends provide equivalent casting.
|
||||||
|
|
||||||
|
This mixin adds a field named 'reference_int'.
|
||||||
|
|
||||||
|
- If the 'reference' field can be cast to an integer, it is stored here
|
||||||
|
- If the 'reference' field *starts* with an integer, it is stored here
|
||||||
|
- Otherwise, we store zero
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
def rebuild_reference_field(self):
|
||||||
|
|
||||||
|
reference = getattr(self, 'reference', '')
|
||||||
|
|
||||||
|
# Default value if we cannot convert to an integer
|
||||||
|
ref_int = 0
|
||||||
|
|
||||||
|
# Look at the start of the string - can it be "integerized"?
|
||||||
|
result = re.match(r"^(\d+)", reference)
|
||||||
|
|
||||||
|
if result and len(result.groups()) == 1:
|
||||||
|
ref = result.groups()[0]
|
||||||
|
try:
|
||||||
|
ref_int = int(ref)
|
||||||
|
except:
|
||||||
|
ref_int = 0
|
||||||
|
|
||||||
|
self.reference_int = ref_int
|
||||||
|
|
||||||
|
reference_int = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
|
||||||
class InvenTreeAttachment(models.Model):
|
class InvenTreeAttachment(models.Model):
|
||||||
""" Provides an abstracted class for managing file attachments.
|
""" Provides an abstracted class for managing file attachments.
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class BuildList(generics.ListCreateAPIView):
|
|||||||
]
|
]
|
||||||
|
|
||||||
ordering_field_aliases = {
|
ordering_field_aliases = {
|
||||||
'reference': ['integer_ref', 'reference'],
|
'reference': ['reference_int', 'reference'],
|
||||||
}
|
}
|
||||||
|
|
||||||
search_fields = [
|
search_fields = [
|
||||||
|
18
InvenTree/build/migrations/0031_build_reference_int.py
Normal file
18
InvenTree/build/migrations/0031_build_reference_int.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.5 on 2021-10-14 06:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('build', '0030_alter_build_reference'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='build',
|
||||||
|
name='reference_int',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
@ -28,7 +28,7 @@ from mptt.exceptions import InvalidMove
|
|||||||
from InvenTree.status_codes import BuildStatus, StockStatus, StockHistoryCode
|
from InvenTree.status_codes import BuildStatus, StockStatus, StockHistoryCode
|
||||||
from InvenTree.helpers import increment, getSetting, normalize, MakeBarcode
|
from InvenTree.helpers import increment, getSetting, normalize, MakeBarcode
|
||||||
from InvenTree.validators import validate_build_order_reference
|
from InvenTree.validators import validate_build_order_reference
|
||||||
from InvenTree.models import InvenTreeAttachment
|
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
|
||||||
|
|
||||||
import common.models
|
import common.models
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ def get_next_build_number():
|
|||||||
return reference
|
return reference
|
||||||
|
|
||||||
|
|
||||||
class Build(MPTTModel):
|
class Build(MPTTModel, ReferenceIndexingMixin):
|
||||||
""" A Build object organises the creation of new StockItem objects from other existing StockItem objects.
|
""" A Build object organises the creation of new StockItem objects from other existing StockItem objects.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
@ -108,6 +108,8 @@ class Build(MPTTModel):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
|
self.rebuild_reference_field()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
except InvalidMove:
|
except InvalidMove:
|
||||||
|
@ -10,8 +10,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from django.db.models import Case, When, Value
|
from django.db.models import Case, When, Value
|
||||||
from django.db.models import BooleanField, IntegerField
|
from django.db.models import BooleanField
|
||||||
from django.db.models.functions import Cast
|
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
@ -72,11 +71,6 @@ class BuildSerializer(InvenTreeModelSerializer):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Annotate with an "integer" version of the reference field, to be used for natural sorting
|
|
||||||
queryset = queryset.annotate(
|
|
||||||
integer_ref=Cast('reference', output_field=IntegerField())
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -156,7 +156,7 @@ class POList(generics.ListCreateAPIView):
|
|||||||
]
|
]
|
||||||
|
|
||||||
ordering_field_aliases = {
|
ordering_field_aliases = {
|
||||||
'reference': ['integer_ref', 'reference'],
|
'reference': ['reference_int', 'reference'],
|
||||||
}
|
}
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
@ -512,7 +512,7 @@ class SOList(generics.ListCreateAPIView):
|
|||||||
]
|
]
|
||||||
|
|
||||||
ordering_field_aliases = {
|
ordering_field_aliases = {
|
||||||
'reference': ['integer_ref', 'reference'],
|
'reference': ['reference_int', 'reference'],
|
||||||
}
|
}
|
||||||
|
|
||||||
filter_fields = [
|
filter_fields = [
|
||||||
|
23
InvenTree/order/migrations/0051_auto_20211014_0623.py
Normal file
23
InvenTree/order/migrations/0051_auto_20211014_0623.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.5 on 2021-10-14 06:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('order', '0050_alter_purchaseorderlineitem_destination'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='reference_int',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='salesorder',
|
||||||
|
name='reference_int',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
@ -28,7 +28,7 @@ from company.models import Company, SupplierPart
|
|||||||
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
|
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
|
||||||
from InvenTree.helpers import decimal2string, increment, getSetting
|
from InvenTree.helpers import decimal2string, increment, getSetting
|
||||||
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus, StockHistoryCode
|
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus, StockStatus, StockHistoryCode
|
||||||
from InvenTree.models import InvenTreeAttachment
|
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
|
||||||
|
|
||||||
|
|
||||||
def get_next_po_number():
|
def get_next_po_number():
|
||||||
@ -89,7 +89,7 @@ def get_next_so_number():
|
|||||||
return reference
|
return reference
|
||||||
|
|
||||||
|
|
||||||
class Order(models.Model):
|
class Order(ReferenceIndexingMixin):
|
||||||
""" Abstract model for an order.
|
""" Abstract model for an order.
|
||||||
|
|
||||||
Instances of this class:
|
Instances of this class:
|
||||||
@ -147,6 +147,9 @@ class Order(models.Model):
|
|||||||
return new_ref
|
return new_ref
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
|
self.rebuild_reference_field()
|
||||||
|
|
||||||
if not self.creation_date:
|
if not self.creation_date:
|
||||||
self.creation_date = datetime.now().date()
|
self.creation_date = datetime.now().date()
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ JSON serializers for the Order API
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.db.models.fields import IntegerField
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@ -12,7 +11,6 @@ from django.core.exceptions import ValidationError as DjangoValidationError
|
|||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import Case, When, Value
|
from django.db.models import Case, When, Value
|
||||||
from django.db.models import BooleanField, ExpressionWrapper, F
|
from django.db.models import BooleanField, ExpressionWrapper, F
|
||||||
from django.db.models.functions import Cast
|
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
@ -75,11 +73,6 @@ class POSerializer(InvenTreeModelSerializer):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Annotate with an "integer" version of the reference field, to be used for natural sorting
|
|
||||||
queryset = queryset.annotate(
|
|
||||||
integer_ref=Cast('reference', output_field=IntegerField())
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
supplier_detail = CompanyBriefSerializer(source='supplier', many=False, read_only=True)
|
supplier_detail = CompanyBriefSerializer(source='supplier', many=False, read_only=True)
|
||||||
@ -435,11 +428,6 @@ class SalesOrderSerializer(InvenTreeModelSerializer):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Annotate with an "integer" version of the reference field, to be used for natural sorting
|
|
||||||
queryset = queryset.annotate(
|
|
||||||
integer_ref=Cast('reference', output_field=IntegerField())
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
customer_detail = CompanyBriefSerializer(source='customer', many=False, read_only=True)
|
customer_detail = CompanyBriefSerializer(source='customer', many=False, read_only=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user