6.4 KiB
Survey Mapping 500 Error Fix
Summary
Fixed a critical server-side error (500 Internal Server Error) that was preventing PUT (update) and DELETE operations on survey template mappings. The error was caused by incorrect field references in the ViewSet configuration.
Problem
When users tried to edit or delete survey template mappings, the server returned a 500 Internal Server Error with the following symptoms:
PUT http://localhost:8000/api/integrations/survey-template-mappings/{id}/ 500 (Internal Server Error)
DELETE http://localhost:8000/api/integrations/survey-template-mappings/{id}/ 500 (Internal Server Error)
Error: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
The server was returning an HTML error page instead of JSON, indicating a server-side exception.
Root Cause
The SurveyTemplateMappingViewSet in apps/integrations/ui_views.py had incorrect field references that didn't match the actual model fields:
Incorrect Configuration (Before Fix):
filterset_fields = ['hospital', 'patient_type_code', 'is_active']
search_fields = ['hospital__name', 'patient_type_name', 'survey_template__name']
ordering_fields = ['hospital', 'patient_type_code', 'priority']
ordering = ['hospital', 'patient_type_code', 'priority']
Issues:
patient_type_code- This field doesn't exist on the model (correct field ispatient_type)patient_type_name- This field doesn't exist on the model (should usepatient_typefor search)priority- This field doesn't exist on the model
Actual Model Fields (from SurveyTemplateMapping model):
patient_type = models.CharField(max_length=20, choices=PatientType.choices, ...)
hospital = models.ForeignKey('organizations.Hospital', ...)
survey_template = models.ForeignKey('surveys.SurveyTemplate', ...)
is_active = models.BooleanField(default=True, ...)
When Django REST Framework tried to apply filters, search, or ordering using these non-existent fields, it raised an exception during queryset processing, causing the 500 error.
Solution
Updated the ViewSet configuration to use the correct field names that exist on the model:
Fixed Configuration (After Fix):
filterset_fields = ['hospital', 'patient_type', 'is_active']
search_fields = ['hospital__name', 'patient_type', 'survey_template__name']
ordering_fields = ['hospital', 'patient_type', 'is_active']
ordering = ['hospital', 'patient_type', 'is_active']
Changes Made:
- Changed
patient_type_code→patient_typein all references - Removed
patient_type_namefrom search_fields (non-existent field) - Removed
priorityfrom ordering_fields and ordering (non-existent field) - Added
is_activeto ordering_fields and ordering for better sorting
File Modified
File: apps/integrations/ui_views.py
Lines Changed: 25-28 (ViewSet configuration)
Impact
Fixed Operations:
- ✅ PUT /api/integrations/survey-template-mappings/{id}/ - Update mapping
- ✅ DELETE /api/integrations/survey-template-mappings/{id}/ - Delete mapping
- ✅ GET /api/integrations/survey-template-mappings/ - List mappings (with proper filtering)
- ✅ GET /api/integrations/survey-template-mappings/{id}/ - Retrieve single mapping
UI Functionality Restored:
- ✅ Edit button on survey mapping settings page now works
- ✅ Delete button on survey mapping settings page now works
- ✅ Filtering by patient type now works correctly
- ✅ Searching by patient type now works correctly
- ✅ Ordering by patient type and active status now works correctly
Testing
To verify the fix:
- Navigate to Survey Template Mappings settings page
- Click "Edit" on an existing mapping
- Verify the modal opens with all fields populated (this was already fixed in previous commit)
- Modify the mapping and click "Save"
- Verify the mapping is updated successfully (should see success message and page reload)
- Click "Delete" on a mapping
- Confirm deletion
- Verify the mapping is deleted successfully
Technical Details
Why This Caused 500 Error:
Django REST Framework's ModelViewSet automatically processes querysets for:
- Filtering (via
filterset_fields) - Searching (via
search_fields) - Ordering (via
ordering_fieldsandordering)
When these configurations reference non-existent fields, Django's ORM raises a FieldError exception during queryset evaluation. Since this exception wasn't caught, it propagated up and resulted in a 500 error.
Why PUT and DELETE Were Affected:
- Both PUT and DELETE operations go through the ViewSet's
get_queryset()method - The queryset processing (filtering, searching, ordering) happens before the actual update/delete
- The exception occurred during this processing phase
Why POST (Create) Still Worked:
- POST operations don't go through queryset processing in the same way
- The serializer validation happens separately, which used correct field names
Related Issues
This fix is part of a series of improvements to the Survey Template Mappings functionality:
- SURVEY_MAPPING_EDIT_MODAL_FIX.md - Fixed the edit modal timing issue (client-side)
- SURVEY_MAPPING_500_ERROR_FIX.md - Fixed the 500 error on PUT/DELETE (server-side) - this document
Both fixes are now complete and the full CRUD functionality for survey template mappings should work correctly.
Notes
- The fix is minimal and surgical - only the problematic field references were corrected
- No changes to the model or serializer were needed
- The fix maintains backward compatibility
- All existing data remains intact
- The fix applies proper ordering by hospital, patient_type, and is_active for better UX
Best Practices Learned
- Always verify field names match model definitions when configuring ViewSet filters, search, and ordering
- Test all CRUD operations when implementing ViewSets, not just GET and POST
- Review error logs when encountering 500 errors to see actual server-side exceptions
- Keep ViewSet configuration aligned with model structure to avoid runtime errors
Related Files
apps/integrations/models.py- SurveyTemplateMapping model definitionapps/integrations/serializers.py- SurveyTemplateMappingSerializer (already correct)apps/integrations/ui_views.py- SurveyTemplateMappingViewSet (FIXED)apps/integrations/urls.py- URL routing (correct)templates/integrations/survey_mapping_settings.html- UI template (previously fixed)