mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +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
|
||||
|
||||
import re
|
||||
import os
|
||||
import logging
|
||||
|
||||
@ -43,6 +44,48 @@ def rename_attachment(instance, 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):
|
||||
""" Provides an abstracted class for managing file attachments.
|
||||
|
||||
|
@ -85,7 +85,7 @@ class BuildList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
'reference': ['integer_ref', 'reference'],
|
||||
'reference': ['reference_int', 'reference'],
|
||||
}
|
||||
|
||||
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.helpers import increment, getSetting, normalize, MakeBarcode
|
||||
from InvenTree.validators import validate_build_order_reference
|
||||
from InvenTree.models import InvenTreeAttachment
|
||||
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
|
||||
|
||||
import common.models
|
||||
|
||||
@ -69,7 +69,7 @@ def get_next_build_number():
|
||||
return reference
|
||||
|
||||
|
||||
class Build(MPTTModel):
|
||||
class Build(MPTTModel, ReferenceIndexingMixin):
|
||||
""" A Build object organises the creation of new StockItem objects from other existing StockItem objects.
|
||||
|
||||
Attributes:
|
||||
@ -108,6 +108,8 @@ class Build(MPTTModel):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
self.rebuild_reference_field()
|
||||
|
||||
try:
|
||||
super().save(*args, **kwargs)
|
||||
except InvalidMove:
|
||||
|
@ -10,8 +10,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django.db.models import Case, When, Value
|
||||
from django.db.models import BooleanField, IntegerField
|
||||
from django.db.models.functions import Cast
|
||||
from django.db.models import BooleanField
|
||||
|
||||
from rest_framework import serializers
|
||||
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
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -156,7 +156,7 @@ class POList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
'reference': ['integer_ref', 'reference'],
|
||||
'reference': ['reference_int', 'reference'],
|
||||
}
|
||||
|
||||
filter_fields = [
|
||||
@ -512,7 +512,7 @@ class SOList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
'reference': ['integer_ref', 'reference'],
|
||||
'reference': ['reference_int', 'reference'],
|
||||
}
|
||||
|
||||
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.helpers import decimal2string, increment, getSetting
|
||||
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():
|
||||
@ -89,7 +89,7 @@ def get_next_so_number():
|
||||
return reference
|
||||
|
||||
|
||||
class Order(models.Model):
|
||||
class Order(ReferenceIndexingMixin):
|
||||
""" Abstract model for an order.
|
||||
|
||||
Instances of this class:
|
||||
@ -147,6 +147,9 @@ class Order(models.Model):
|
||||
return new_ref
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
self.rebuild_reference_field()
|
||||
|
||||
if not self.creation_date:
|
||||
self.creation_date = datetime.now().date()
|
||||
|
||||
|
@ -4,7 +4,6 @@ JSON serializers for the Order API
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
from django.db.models.fields import IntegerField
|
||||
|
||||
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.models import Case, When, Value
|
||||
from django.db.models import BooleanField, ExpressionWrapper, F
|
||||
from django.db.models.functions import Cast
|
||||
|
||||
from rest_framework import serializers
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
customer_detail = CompanyBriefSerializer(source='customer', many=False, read_only=True)
|
||||
|
Loading…
Reference in New Issue
Block a user