Fixed up some stupid recursion on the Tree model template

This commit is contained in:
Oliver Walters 2019-06-18 00:59:54 +10:00
parent 642660d76e
commit 16b6ae8d61
8 changed files with 73 additions and 39 deletions

View File

@ -11,6 +11,8 @@ from rest_framework.exceptions import ValidationError
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from .validators import validate_tree_name
class InvenTreeTree(models.Model):
""" Provides an abstracted self-referencing tree model for data categories.
@ -31,7 +33,8 @@ class InvenTreeTree(models.Model):
name = models.CharField(
blank=False,
max_length=100,
unique=True
unique=True,
validators=[validate_tree_name]
)
description = models.CharField(
@ -104,14 +107,6 @@ class InvenTreeTree(models.Model):
""" True if there are any children under this item """
return self.children.count() > 0
@property
def children(self):
""" Return the children of this item """
contents = ContentType.objects.get_for_model(type(self))
childs = contents.get_all_objects_for_this_type(parent=self.id)
return childs
def getAcceptableParents(self):
""" Returns a list of acceptable parent items within this model
Acceptable parents are ones which are not underneath this item.
@ -164,8 +159,8 @@ class InvenTreeTree(models.Model):
"""
return '/'.join([item.name for item in self.path])
def __setattr__(self, attrname, val):
""" Custom Attribute Setting function
def clean(self):
""" Custom cleaning
Parent:
Setting the parent of an item to its own child results in an infinite loop.
@ -177,28 +172,18 @@ class InvenTreeTree(models.Model):
Tree node names are limited to a reduced character set
"""
if attrname == 'parent_id':
# If current ID is None, continue
# - This object is just being created
if self.id is None:
pass
# Parent cannot be set to same ID (this would cause looping)
elif val == self.id:
raise ValidationError("Category cannot set itself as parent")
# Null parent is OK
elif val is None:
pass
# Ensure that the new parent is not already a child
else:
kids = self.getUniqueChildren()
if val in kids:
raise ValidationError("Category cannot set a child as parent")
super().clean()
# Prohibit certain characters from tree node names
elif attrname == 'name':
val = val.translate({ord(c): None for c in "!@#$%^&*'\"\\/[]{}<>,|+=~`"})
# Parent cannot be set to same ID (this would cause looping)
try:
if self.parent.id == self.id:
raise ValidationError("Category cannot set itself as parent")
except:
pass
super(InvenTreeTree, self).__setattr__(attrname, val)
# Ensure that the new parent is not already a child
if self.id in self.getUniqueChildren():
raise ValidationError("Category cannot set a child as parent")
def __str__(self):
""" String representation of a category is the full path to that category """

View File

@ -17,6 +17,14 @@ def validate_part_name(value):
)
def validate_tree_name(value):
""" Prevent illegal characters in tree item names """
for c in "!@#$%^&*'\"\\/[]{}<>,|+=~`\"":
if c in str(value):
raise ValidationError({'name': _('Illegal character in name')})
def validate_overage(value):
""" Validate that a BOM overage string is properly formatted.

View File

@ -52,10 +52,8 @@ class TreeSerializer(views.APIView):
if item.has_children:
nodes = []
"""
for child in item.children.all().order_by('name'):
nodes.append(self.itemToJson(child))
"""
data['nodes'] = nodes

View File

@ -35,8 +35,6 @@ class PartCategoryTree(TreeSerializer):
return reverse('part-index')
def get_items(self):
print("hello world")
return PartCategory.objects.all().prefetch_related('parts', 'children')
@ -112,7 +110,9 @@ class PartList(generics.ListCreateAPIView):
if cat_id:
try:
category = PartCategory.objects.get(pk=cat_id)
parts_list = parts_list.filter(category__in=category.getUniqueChildren())
cats = [category.id]
cats += [cat for cat in category.getUniqueChildren()]
parts_list = parts_list.filter(category__in=cats)
except PartCategory.DoesNotExist:
pass

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.2 on 2019-06-17 14:42
import InvenTree.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('part', '0007_auto_20190602_1944'),
]
operations = [
migrations.AlterField(
model_name='partcategory',
name='name',
field=models.CharField(max_length=100, unique=True, validators=[InvenTree.validators.validate_tree_name]),
),
]

View File

@ -73,10 +73,12 @@ class PartCategory(InvenTreeTree):
(including children of child categories)
"""
cats = [self.id]
if cascade:
query = Part.objects.filter(category__in=self.getUniqueChildren())
else:
query = Part.objects.filter(category=self)
cats += [cat for cat in self.getUniqueChildren()]
query = Part.objects.filter(category__in=cats)
if active:
query = query.filter(active=True)

View File

@ -38,6 +38,9 @@ class StockCategoryTree(TreeSerializer):
def root_url(self):
return reverse('stock-index')
def get_items(self):
return StockLocation.objects.all().prefetch_related('stock_items', 'children')
class StockDetail(generics.RetrieveUpdateDestroyAPIView):
""" API detail endpoint for Stock object

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.2 on 2019-06-17 14:42
import InvenTree.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0006_stockitem_purchase_order'),
]
operations = [
migrations.AlterField(
model_name='stocklocation',
name='name',
field=models.CharField(max_length=100, unique=True, validators=[InvenTree.validators.validate_tree_name]),
),
]