Improve validators for 'filters' field

This commit is contained in:
Oliver Walters 2021-01-14 08:15:05 +11:00
parent 88a7b3251d
commit 9884fe5c5e
3 changed files with 65 additions and 9 deletions

View File

@ -12,7 +12,7 @@ from decimal import Decimal
from wsgiref.util import FileWrapper from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse from django.http import StreamingHttpResponse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError, FieldError
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
@ -414,7 +414,7 @@ def extract_serial_numbers(serials, expected_quantity):
return numbers return numbers
def validateFilterString(value): def validateFilterString(value, model=None):
""" """
Validate that a provided filter string looks like a list of comma-separated key=value pairs Validate that a provided filter string looks like a list of comma-separated key=value pairs
@ -464,6 +464,15 @@ def validateFilterString(value):
results[k] = v results[k] = v
# If a model is provided, verify that the provided filters can be used against it
if model is not None:
try:
query = model.objects.filter(**results)
except FieldError as e:
raise ValidationError(
str(e),
)
return results return results

View File

@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2021-01-13 12:02
from django.db import migrations, models
import label.models
class Migration(migrations.Migration):
dependencies = [
('label', '0004_auto_20210111_2302'),
]
operations = [
migrations.AlterField(
model_name='stockitemlabel',
name='filters',
field=models.CharField(blank=True, help_text='Query filters (comma-separated list of key=value pairs', max_length=250, validators=[label.models.validate_stock_item_filters], verbose_name='Filters'),
),
migrations.AlterField(
model_name='stocklocationlabel',
name='filters',
field=models.CharField(blank=True, help_text='Query filters (comma-separated list of key=value pairs', max_length=250, validators=[label.models.validate_stock_location_filters], verbose_name='Filters'),
),
]

View File

@ -28,6 +28,20 @@ def rename_label(instance, filename):
return os.path.join('label', 'template', instance.SUBDIR, filename) return os.path.join('label', 'template', instance.SUBDIR, filename)
def validate_stock_item_filters(filters):
filters = validateFilterString(filters, model=stock.models.StockItem)
return filters
def validate_stock_location_filters(filters):
filters = validateFilterString(filters, model=stock.models.StockLocation)
return filters
class LabelTemplate(models.Model): class LabelTemplate(models.Model):
""" """
Base class for generic, filterable labels. Base class for generic, filterable labels.
@ -71,13 +85,6 @@ class LabelTemplate(models.Model):
validators=[FileExtensionValidator(allowed_extensions=['html'])], validators=[FileExtensionValidator(allowed_extensions=['html'])],
) )
filters = models.CharField(
blank=True, max_length=250,
help_text=_('Query filters (comma-separated list of key=value pairs'),
verbose_name=_('Filters'),
validators=[validateFilterString]
)
enabled = models.BooleanField( enabled = models.BooleanField(
default=True, default=True,
verbose_name=_('Enabled'), verbose_name=_('Enabled'),
@ -125,6 +132,14 @@ class StockItemLabel(LabelTemplate):
SUBDIR = "stockitem" SUBDIR = "stockitem"
filters = models.CharField(
blank=True, max_length=250,
help_text=_('Query filters (comma-separated list of key=value pairs'),
verbose_name=_('Filters'),
validators=[
validate_stock_item_filters]
)
def matches_stock_item(self, item): def matches_stock_item(self, item):
""" """
Test if this label template matches a given StockItem object Test if this label template matches a given StockItem object
@ -170,6 +185,14 @@ class StockLocationLabel(LabelTemplate):
SUBDIR = "stocklocation" SUBDIR = "stocklocation"
filters = models.CharField(
blank=True, max_length=250,
help_text=_('Query filters (comma-separated list of key=value pairs'),
verbose_name=_('Filters'),
validators=[
validate_stock_location_filters]
)
def matches_stock_location(self, location): def matches_stock_location(self, location):
""" """
Test if this label template matches a given StockLocation object Test if this label template matches a given StockLocation object