Saved Query Filter Loading - Diagnosis Guide

Problem Statement

When editing a saved query, the visual query builder was not displaying the saved filter conditions from the database.

Root Cause Analysis

The issue was that query_json (containing the saved filters) was not being passed to the edit template, or was being passed but not loaded correctly by Alpine.js.

Diagnostic Changes Made

1. View-Side Logging (eneza_workflow_engine/views/querybuilder.py)

Added debug logging to SaveQueryDetailView.get_context_data() when edit=1:

python
# Debug logging (lines 234-244)
import sys
print(f"\n=== SaveQueryDetailView Edit Mode Debug ===", file=sys.stderr)
print(f"Query ID: {self.object.id}", file=sys.stderr)
print(f"Query Name: {self.object.name}", file=sys.stderr)
print(f"Filters JSON from DB: {self.object.filters_json}", file=sys.stderr)
print(f"Query JSON (serialized): {context['query_json']}", file=sys.stderr)
print(f"Models Count: {len(allowed_models)}", file=sys.stderr)
print(f"Filters by Model Keys: {list(filters_by_model.keys())}", file=sys.stderr)
print("==========================================\n", file=sys.stderr)

What to check: When accessing the edit view, check Django's stderr output in your terminal for: - ✅ Query ID, Name, and content type model - ✅ Raw JSON structure from database - ✅ Count of allowed models - ✅ Available filter keys (should match model slugs)

2. Template-Side Logging (eneza_workflow_engine/templates/saved_query/partials/edit_query_builder_partial.html)

Added comprehensive console logging in the initialization function:

javascript
// Initialization logging (lines 22-31)
console.log('=== Initializing Edit Query Builder ===');
console.log('Query ID:', parseInt('{{ object.id }}'));
console.log('Query Name:', `{{ object.name }}`);
console.log('Selected Model:', `{{ object.content_type.model }}`);

let filtersByModel = {};
try {
    filtersByModel = JSON.parse('{{ filters_by_model_json|escapejs }}');
    console.log('Filters by Model loaded:', Object.keys(filtersByModel));
} catch (e) {
    console.error('Error parsing filters_by_model_json:', e);
}

And in the loadQueryData() function (lines 79-124):

javascript
// Query data loading logging
console.log('Query JSON String from template:', queryJsonString);
console.log('Parsed query data:', queryData);
console.log('Loaded groups from saved query:', this.groups);
console.error('Error loading query data:', error); // If error occurs

What to check: Open browser DevTools (F12) → Console tab and look for: - ✅ "Initializing Edit Query Builder" message - ✅ Query ID, Name, and Model name logged - ✅ Filters by Model keys listed - ✅ "Query JSON String from template" message with full JSON - ✅ "Parsed query data" showing the structure - ✅ "Loaded groups from saved query" showing reconstructed conditions

Diagnostic Flow

  1. HTMX makes GET request with ?edit=1 parameter
  2. Django view calls get_context_data() with edit mode
  3. View creates query_json from self.object.filters_json
  4. View injects template variables (Django template rendering)
  5. Browser loads edit template partial
  6. JavaScript executes initialization function
  7. Alpine.js parses template variables and reconstructs UI

Possible Failure Points:

  1. Django: Context variable not in context dict
  2. Django: JSON serialization fails (malformed data)
  3. Template: Template variable not rendered (Django templating issue)
  4. JavaScript: JSON parsing fails (malformed JSON after escaping)
  5. Alpine.js: Component not initialized for HTMX-loaded content

Testing Steps

  1. Check Django Logs: bash # Terminal running Django dev server python manage.py runserver 2>&1 | grep "SaveQueryDetailView\|Filters JSON\|Query JSON"

  2. Check Browser Console: - Open DevTools (F12) - Go to Console tab - Click "Edit" button on a saved query - Look for initialization messages and data

  3. Inspect Network Request: - DevTools → Network tab - Click Edit button - Look for the HTMX request - Check Response tab for rendered HTML - Verify {{ query_json|escapejs }} is replaced with actual JSON

  4. Check Template Rendering: - Right-click in browser → Inspect Element - Find the <script> tag in edit template - Check if template variables are properly rendered - Look for lines like: const queryData = JSON.parse('{"condition":"AND","groups":[...]}')

Expected Output Examples

Terminal (Django Server):

text
=== SaveQueryDetailView Edit Mode Debug ===
Query ID: 1
Query Name: Customer Filter
Filters JSON from DB: {'condition': 'AND', 'groups': [{'condition': 'AND', 'rules': [...]}]}
Query JSON (serialized): {"condition":"AND","groups":[...]}
Models Count: 3
Filters by Model Keys: ['customer', 'order', 'invoice']
==========================================

Browser Console:

text
=== Initializing Edit Query Builder ===
Query ID: 1
Query Name: Customer Filter
Selected Model: customer
Filters by Model loaded: (3) ['customer', 'order', 'invoice']

Query JSON String from template: {"condition":"AND","groups":[{"condition":"AND","rules":[{"field":"name","operator":"contains","value":"Test"}]}]}
Parsed query data: {condition: "AND", groups: Array(1), ...}
Loaded groups from saved query: (1) [{id: 1707518XXX, condition: "AND", rules: Array(1)}, ...]

Next Steps If Issue Persists

  1. If terminal shows empty/null JSON: - Check SavedQuery model in database - Verify filters_json column has data - Check if self.object is properly loaded

  2. If console shows parse error: - The JSON is malformed - Check template variable escaping - Verify no special characters breaking JSON string

  3. If console shows empty groups: - JSON parsed but no groups structure - Check if saved query was created with new format - May need format conversion

  4. If Alpine not initializing: - Verify Alpine.js library is loaded - Check for JavaScript errors above the component - Ensure htmx:afterSettle event is firing

Files Modified

  1. eneza_workflow_engine/views/querybuilder.py - Added debug logging to SaveQueryDetailView.get_context_data()
  2. eneza_workflow_engine/templates/saved_query/partials/edit_query_builder_partial.html - Enhanced loadQueryData() with comprehensive logging

How to Remove Debug Code

Once issue is resolved, remove the debug logging: - Remove sys.stderr print statements from querybuilder.py - Remove console.log() statements from template - Keep the error handling structure