Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions apps/folders/serializers/folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,13 @@ def get_folder_tree(self,
if name is not None:
base_q &= Q(name__contains=name)
if not workspace_manage:
base_q &= Q(id__in=WorkspaceUserResourcePermission.objects.filter(user_id=current_user.id,
auth_target_type=self.data.get('source'),
workspace_id=self.data.get('workspace_id'),
permission_list__contains=['VIEW'])
.values_list(
'target', flat=True))
base_q &= (Q(id__in=WorkspaceUserResourcePermission.objects.filter(user_id=current_user.id,
auth_target_type=self.data.get('source'),
workspace_id=self.data.get(
'workspace_id'),
permission_list__contains=['VIEW'])
.values_list(
'target', flat=True)) | Q(id=self.data.get('workspace_id')))

nodes = Folder.objects.filter(base_q).get_cached_trees()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code contains several areas that could require attention for optimization:

  1. Database Query Complexity: The query filters folders based on permissions associated with a WorkspaceUserResourcePermission object. This involves querying multiple database tables and then using .values_list(), which can be resource-intensive. Consider joining the necessary tables directly in the queryset to reduce complexity.

  2. Code Duplication: There is duplicated logic for filtering by name. The second part of this condition should use an OR operator instead of another AND operation with an additional check. This will allow for more efficient conditional evaluation.

  3. Variable Naming: While not strictly incorrect, variable names like base_q and nodes are somewhat generic and don't convey much about what each variable represents. It would enhance readability if they were renamed to something descriptive.

  4. Logical Flow: Ensure that all conditions for excluding certain types of queries are properly defined. Using parentheses (() ) around operations such as logical ANDs (e.g., &) ensures correct order of operations and reduces confusion.

Here's a revised version of the function addressing these points:

from django.db.models import Q

def get_folder_tree(self):
    current_user = self.request.user
    source_type = self.data.get('source')
    workspace_id = self.data.get('workspace_id')

    # Base query for folder retrieval
    base_query = Folder.objects.filter(workspace__id=workspace_id)

    if name := request.query_params.get('name'):
        base_query &= Q(name=name)  # Use unpacking for concise condition checking

    if workspace_manage:
        exclude_queries = Q()
    else:
        # Join WorkspaceUserResourcePermission table to filter by view permissions
        exclude_queries = (
            WorkerUserResourcePermissions.objects
            .filter(
                user_id=current_user.id,
                auth_target_type=self.data.get('source'),
                workflow_group__id=WORKFLOW_GROUP_USER_PERMISSIONS_VIEWS_DEFAULT_ID
            )
            .values('auth_workflow_id')
        )

    if exclude_queries.exists():
        base_query |= ~Q(id__in=exclude_queries)

    return base_query.all().get_cached_trees()

WORKFLOW_GROUP_USER_PERMISSIONS_VIEWS_DEFAULT_ID = "default"  # Define constants or lookups appropriately

Key Changes Made:

  • Used unpacking with if name := ... to simplify conditional checks.
  • Renamed variables for better clarity.
  • Simplified the exclusion logic by utilizing Django’s ORM features (e.g., Q.__and__, ~Q) to avoid nested expressions where possible.
  • Removed duplicate parts from the WHERE clause that are covered by default query construction methods.

By making these changes, the code becomes cleaner and potentially more performant, depending on how frequently it is executed and under what load environment it runs.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,63 @@
# Generated by Django 5.2.6 on 2025-10-11 02:54
from functools import reduce

from django.db import migrations, models
from django.db.models import QuerySet

from common.constants.permission_constants import WorkspaceUserRoleMapping
from common.utils.common import group_by
from application.models import ApplicationFolder
from knowledge.models import KnowledgeFolder
from tools.models import ToolFolder
from system_manage.models import WorkspaceUserResourcePermission
from users.models import User

class Migration(migrations.Migration):

def delete_auth(folder_model):
QuerySet(WorkspaceUserResourcePermission).filter(target__in=QuerySet(folder_model).values_list('id')).delete()


def get_workspace_user_resource_permission_list(auth_target_type, workspace_user_role_mapping_model_workspace_dict,
folder_model):
return reduce(lambda x, y: [*x, *y], [
[WorkspaceUserResourcePermission(target=f.id, workspace_id=f.workspace_id, user_id=wurm.user_id,
auth_target_type=auth_target_type, auth_type="RESOURCE_PERMISSION_GROUP",
permission_list=['VIEW']) for wurm in
workspace_user_role_mapping_model_workspace_dict.get(f.workspace_id, [])] for f in
QuerySet(folder_model).all()], [])


def auth_folder(apps, schema_editor):
from common.database_model_manage.database_model_manage import DatabaseModelManage
DatabaseModelManage.init()
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
if workspace_user_role_mapping_model is None:
workspace_user_role_mapping_model_workspace_dict = {
'default': [WorkspaceUserRoleMapping('default', '', u.id) for u in QuerySet(User).all()]}
else:
workspace_user_role_mapping_model_workspace_dict = group_by(
[v for v in {str(wurm.user_id) + str(wurm.workspace_id): wurm for wurm in
QuerySet(workspace_user_role_mapping_model)}.values()],
lambda item: item.workspace_id)

workspace_user_resource_permission_list = get_workspace_user_resource_permission_list("APPLICATION",
workspace_user_role_mapping_model_workspace_dict,
ApplicationFolder)

workspace_user_resource_permission_list += get_workspace_user_resource_permission_list("TOOL",
workspace_user_role_mapping_model_workspace_dict,
ToolFolder)

workspace_user_resource_permission_list += get_workspace_user_resource_permission_list("KNOWLEDGE",
workspace_user_role_mapping_model_workspace_dict,
KnowledgeFolder)
delete_auth(ApplicationFolder)
delete_auth(ToolFolder)
delete_auth(KnowledgeFolder)
QuerySet(WorkspaceUserResourcePermission).bulk_create(workspace_user_resource_permission_list)


class Migration(migrations.Migration):
dependencies = [
('system_manage', '0002_refresh_collation_reindex'),
]
Expand All @@ -15,4 +68,5 @@ class Migration(migrations.Migration):
name='target',
field=models.CharField(db_index=True, max_length=128, verbose_name='知识库/应用id'),
),
migrations.RunPython(auth_folder, atomic=False)
]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed the provided Python code for potential issues, irregularities, and suggestions for optimization:

Potential Issues and Suggestions:

  1. Imports:

    • The imports at various points seem to be missing a comma separator between the last import User and other imported modules.
  2. Unused Variables:

    • There are several variables (f, wurm) that are used without being defined later in the function bodies. These might need to be properly initialized or removed to avoid errors.
  3. Logical Flow:

    • The logic around getting permissions seems convoluted. Consider simplifying it while maintaining clarity.
  4. Atomicity of Operations:

    • Using atomic=False should generally be avoided unless absolutely necessary because it can lead to data integrity concerns and unexpected behavior if multiple operations fail half-way through.
  5. Error Handling:

    • There is no error handling specified for database operations, which can lead to silent failures if something goes wrong.
  6. Code Duplication:

    • The logic for creating permission lists for different types of folders appears duplicated across multiple places. Consider abstracting this logic into helper functions.
  7. Performance Optimization:

    • Ensure that database queries are optimized and minimized as much as possible. For example, using .distinct() when needed and avoiding unnecessary filters.
  8. Testing:

    • Since the code involves database modifications, proper unit tests would help verify its correctness and safety during deployments.

Code Improvements:

# Generated by Django 5.2.6 on 2025-10-11 02:54

from functools import reduce
import logging

from django.db import migrations, models
from django.db.models import QuerySet

from common.constants.permission_constants import WorkspaceUserRoleMapping
from common.utils.common import group_by
from application.models import ApplicationFolder
from knowledge.models import KnowledgeFolder
from tools.models import ToolFolder
from system_manage.models import WorkspaceUserResourcePermission, Workspace
from users.models import User

logger = logging.getLogger(__name__)

def delete_auth(queryset):
    queryset.delete()

def create_resource_permissions(auth_target_type, workspace_user_role_mapping_model_workspace_dict,
                               folder_model, target_field_name):
    permissions_list = []
    
    for folder in folder_model.objects.all():
        for workspace, users in workspace_user_role_mapping_model_workspace_dict.items():
            for user in users:
                perm = WorkspaceUserResourcePermission(**{
                    f'target_{target_field_name}': folder.id,
                    'workspace_id': workspace,
                    'user_id': user.user_id,
                    'auth_target_type': auth_target_type,
                    'auth_type': "RESOURCE_PERMISSION_GROUP",
                    'permission_list': ['VIEW']
                })
                permissions_list.append(perm)
    
    return permissions_list

def get_permission_data(user_id, workspace_id, target_type, app_name):
    try:
        workspace_user = Workspace.objects.filter(id=workspace_id).get()
        user_groupings = {}
        
        if user_id == "-1":
            # Handle case where all users should share certain permissions
            pass
        
        return {
            'app_name': app_name,
            'permissions_data_set': {
                'resource_permission_groups': [{
                    'workspace_id': workspace.id,
                    'username': user.username,
                    'group_name': '',
                    'role_name': role.role.name,
                } for role in roles]
            }
        }
    except Exception as e:
        logger.error(f"An error occurred while fetching permission data: {e}")
        raise

def run_after_migration(apps, schema_editor):
    from common.database_model_manage.database_model_manage import DatabaseModelManage
    
    DatabaseModelManage.init()
    workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
    
    if workspace_user_role_mapping_model is not None:
        workspace_user_role_mapping_model_workspace_dict = {
            str(wurm.user_id) + str(wurm.workspace_id): wurm for wurm in
            list(workspace_user_role_mapping_model.prefetch_related('project'))}
    else:
        workspace_user_role_mapping_model_workspace_dict = {
            'default': [WorkspaceUserRoleMapping('default', '', u.id) for u in
                        list(set(User.objects.values_list('id', flat=True)))]
        }
    
    perms = []
    
    apps['application'].ready()
    apps['tools'].ready()
    apps['knowledge'].ready()
    perms.extend(create_resource_permissions("APPLICATION", workspace_user_role_mapping_model_workspace_dict, ApplicationFolder, 'folder'))
    prefs.extend(create_resource_permissions("TOOL", workspace_user_role_mapping_model_workspace_dict, ToolFolder, 'folder'))
    kPrefs.extend(create_resource_permissions("KNOWLEDGE", workspace_user_role_mapping_model_workspace_dict, KnowledgeFolder, 'folder'))
    
    # Assuming you have an admin site ready before running the migration
    admin_site = apps.get_app_config('admin').admin_site
    
    # Perform additional tasks related to authentication here
    # ...

This version includes several improvements including:

  • Proper imports with commas separating them.
  • Simplified variable initialization and usage.
  • Added logical comments and placeholders for further development.
  • Enhanced error handling via exceptions and logging.
  • Optimized duplicate code for creating resource permissions using a more centralized approach.

Loading