Unverified Commit ab9d457c authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #1312 from jumpserver/bugfix_asset_tree_node

修复:资产树节点,取消model value unique,并添加唯一性校验,serializers/api中;修改新增节点计数器规则;
parents 84d3fa6d cbc4a0a9
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
# limitations under the License. # limitations under the License.
from rest_framework import generics, mixins from rest_framework import generics, mixins
from rest_framework.serializers import ValidationError
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet from rest_framework_bulk import BulkModelViewSet
...@@ -45,16 +46,15 @@ class NodeViewSet(BulkModelViewSet): ...@@ -45,16 +46,15 @@ class NodeViewSet(BulkModelViewSet):
def get_serializer_class(self): def get_serializer_class(self):
show_current_asset = self.request.query_params.get('show_current_asset') show_current_asset = self.request.query_params.get('show_current_asset')
print(show_current_asset)
if show_current_asset: if show_current_asset:
return serializers.NodeCurrentSerializer return serializers.NodeCurrentSerializer
else: else:
return serializers.NodeSerializer return serializers.NodeSerializer
def perform_create(self, serializer): # def perform_create(self, serializer):
child_key = Node.root().get_next_child_key() # child_key = Node.root().get_next_child_key()
serializer.validated_data["key"] = child_key # serializer.validated_data["key"] = child_key
serializer.save() # serializer.save()
class NodeWithAssetsApi(generics.ListAPIView): class NodeWithAssetsApi(generics.ListAPIView):
...@@ -91,16 +91,29 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): ...@@ -91,16 +91,29 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
serializer_class = serializers.NodeSerializer serializer_class = serializers.NodeSerializer
instance = None instance = None
def counter(self):
values = [
child.value[child.value.rfind(' '):]
for child in self.get_object().get_children()
if child.value.startswith("新节点 ")
]
values = [int(value) for value in values if value.strip().isdigit()]
count = max(values)+1 if values else 1
return count
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if not request.data.get("value"): if not request.data.get("value"):
request.data["value"] = _("New node {}").format( request.data["value"] = _("New node {}").format(self.counter())
Node.root().get_next_child_key().split(":")[-1]
)
return super().post(request, *args, **kwargs) return super().post(request, *args, **kwargs)
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
instance = self.get_object() instance = self.get_object()
value = request.data.get("value") value = request.data.get("value")
values = [child.value for child in instance.get_children()]
if value in values:
raise ValidationError(
'The same level node name cannot be the same'
)
node = instance.create_child(value=value) node = instance.create_child(value=value)
return Response( return Response(
{"id": node.id, "key": node.key, "value": node.value}, {"id": node.id, "key": node.key, "value": node.value},
...@@ -199,6 +212,9 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView): ...@@ -199,6 +212,9 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView):
instance = self.get_object() instance = self.get_object()
if instance != Node.root(): if instance != Node.root():
instance.assets.remove(*tuple(assets)) instance.assets.remove(*tuple(assets))
else:
assets = [asset for asset in assets if asset.nodes.count() > 1]
instance.assets.remove(*tuple(assets))
class NodeReplaceAssetsApi(generics.UpdateAPIView): class NodeReplaceAssetsApi(generics.UpdateAPIView):
......
...@@ -12,7 +12,10 @@ __all__ = ['Node'] ...@@ -12,7 +12,10 @@ __all__ = ['Node']
class Node(models.Model): class Node(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
key = models.CharField(unique=True, max_length=64, verbose_name=_("Key")) # '1:1:1:1' key = models.CharField(unique=True, max_length=64, verbose_name=_("Key")) # '1:1:1:1'
value = models.CharField(max_length=128, unique=True, verbose_name=_("Value")) # value = models.CharField(
# max_length=128, unique=True, verbose_name=_("Value")
# )
value = models.CharField(max_length=128, verbose_name=_("Value"))
child_mark = models.IntegerField(default=0) child_mark = models.IntegerField(default=0)
date_create = models.DateTimeField(auto_now_add=True) date_create = models.DateTimeField(auto_now_add=True)
...@@ -48,7 +51,7 @@ class Node(models.Model): ...@@ -48,7 +51,7 @@ class Node(models.Model):
return child return child
def get_children(self): def get_children(self):
return self.__class__.objects.filter(key__regex=r'{}:[0-9]+$'.format(self.key)) return self.__class__.objects.filter(key__regex=r'^{}:[0-9]+$'.format(self.key))
def get_all_children(self): def get_all_children(self):
return self.__class__.objects.filter(key__startswith='{}:'.format(self.key)) return self.__class__.objects.filter(key__startswith='{}:'.format(self.key))
......
...@@ -51,6 +51,18 @@ class NodeSerializer(serializers.ModelSerializer): ...@@ -51,6 +51,18 @@ class NodeSerializer(serializers.ModelSerializer):
fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_node'] fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_node']
list_serializer_class = BulkListSerializer list_serializer_class = BulkListSerializer
def validate(self, data):
value = data.get('value')
instance = self.instance
if not instance.is_root():
children = instance.parent.get_children().exclude(key=instance.key)
values = [child.value for child in children]
if value in values:
raise serializers.ValidationError(
'The same level node name cannot be the same'
)
return data
@staticmethod @staticmethod
def get_parent(obj): def get_parent(obj):
return obj.parent.id return obj.parent.id
......
...@@ -98,7 +98,10 @@ function initTree2() { ...@@ -98,7 +98,10 @@ function initTree2() {
$.get("{% url 'api-assets:node-list' %}", function(data, status){ $.get("{% url 'api-assets:node-list' %}", function(data, status){
$.each(data, function (index, value) { $.each(data, function (index, value) {
value["pId"] = value["parent"]; value["pId"] = value["parent"];
value["open"] = true; {#value["open"] = true;#}
if (value["key"] === "0") {
value["open"] = true;
}
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')'; value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
value['value'] = value['value']; value['value'] = value['value'];
}); });
......
...@@ -190,7 +190,7 @@ ...@@ -190,7 +190,7 @@
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Nodes' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Nodes' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes_remain %} {% for node in nodes_remain %}
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.name }}</option> <option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
...@@ -204,7 +204,7 @@ ...@@ -204,7 +204,7 @@
{% for node in asset.nodes.all %} {% for node in asset.nodes.all %}
<tr> <tr>
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node.name }}</b></td> <td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td>
<td> <td>
<button class="btn btn-danger pull-right btn-xs btn-leave-node" type="button"><i class="fa fa-minus"></i></button> <button class="btn btn-danger pull-right btn-xs btn-leave-node" type="button"><i class="fa fa-minus"></i></button>
</td> </td>
......
...@@ -211,6 +211,8 @@ function addTreeNode() { ...@@ -211,6 +211,8 @@ function addTreeNode() {
}; };
newNode.checked = zTree.getSelectedNodes()[0].checked; newNode.checked = zTree.getSelectedNodes()[0].checked;
zTree.addNodes(parentNode, 0, newNode); zTree.addNodes(parentNode, 0, newNode);
var node = zTree.getNodeByParam('id', newNode.id, parentNode)
zTree.editName(node);
} else { } else {
alert("{% trans 'Create node failed' %}") alert("{% trans 'Create node failed' %}")
} }
...@@ -241,9 +243,9 @@ function removeTreeNode() { ...@@ -241,9 +243,9 @@ function removeTreeNode() {
function editTreeNode() { function editTreeNode() {
hideRMenu(); hideRMenu();
var current_node = zTree.getSelectedNodes()[0]; var current_node = zTree.getSelectedNodes()[0];
if (!current_node){ if (!current_node){
return return
} }
if (current_node.value) { if (current_node.value) {
current_node.name = current_node.value; current_node.name = current_node.value;
...@@ -398,9 +400,9 @@ function initTree() { ...@@ -398,9 +400,9 @@ function initTree() {
$.get("{% url 'api-assets:node-list' %}", query_params, function(data, status){ $.get("{% url 'api-assets:node-list' %}", query_params, function(data, status){
$.each(data, function (index, value) { $.each(data, function (index, value) {
value["pId"] = value["parent"]; value["pId"] = value["parent"];
{#if (value["key"] === "0") {#} if (value["key"] === "0") {
value["open"] = true; value["open"] = true;
{# }#} }
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')'; value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
value['value'] = value['value']; value['value'] = value['value'];
}); });
......
...@@ -68,7 +68,7 @@ var asset_table; ...@@ -68,7 +68,7 @@ var asset_table;
function initTable() { function initTable() {
if (inited){ if (inited){
return return asset_table
} else { } else {
inited = true; inited = true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment