mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Fixed up some stupid recursion on the Tree model template
This commit is contained in:
parent
642660d76e
commit
16b6ae8d61
@ -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 """
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
19
InvenTree/part/migrations/0008_auto_20190618_0042.py
Normal file
19
InvenTree/part/migrations/0008_auto_20190618_0042.py
Normal 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]),
|
||||
),
|
||||
]
|
@ -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)
|
||||
|
@ -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
|
||||
|
19
InvenTree/stock/migrations/0007_auto_20190618_0042.py
Normal file
19
InvenTree/stock/migrations/0007_auto_20190618_0042.py
Normal 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]),
|
||||
),
|
||||
]
|
Loading…
Reference in New Issue
Block a user