4.5 KiB
Survey Mapping UUID Fix - Complete
Problem
When trying to create or edit survey template mappings in the admin interface, users were getting validation errors:
{
"hospital": [
"Invalid pk \"8\" - object does not exist."
],
"survey_template": [
"Invalid pk \"2\" - object does not exist."
]
}
Root Cause Analysis
Database Structure
- Hospitals use UUID primary keys (e.g.,
8ccecfba-ec98-446a-9d0f-61bf5b49bc8d) - Survey Templates use UUID primary keys (e.g.,
bcff8a0c-2ec2-42e6-ac78-9f203d0c6a84)
The Bug
The JavaScript in templates/integrations/survey_mapping_settings.html was incorrectly using parseInt() on the dropdown values:
const data = {
hospital: parseInt(document.getElementById('hospital').value),
patient_type: document.getElementById('patientType').value,
survey_template: parseInt(document.getElementById('surveyTemplate').value),
is_active: document.getElementById('isActive').checked
};
When parseInt() was called on UUID strings, it would:
- Attempt to parse the UUID as an integer
- Parse only the first numeric characters (e.g.,
8ccecfba...→8) - Send these invalid integer IDs to the API
- The Django Rest Framework serializer would fail to find objects with those IDs
Evidence from Database
Running python manage.py check_mapping_data showed:
- 2 hospitals with UUID IDs
- 8 survey templates with UUID IDs
- All templates belonged to hospital
8ccecfba-ec98-446a-9d0f-61bf5b49bc8d
Solution
Changed File
templates/integrations/survey_mapping_settings.html
Fix Applied
Removed parseInt() calls from the JavaScript data object:
const data = {
hospital: document.getElementById('hospital').value, // Removed parseInt()
patient_type: document.getElementById('patientType').value,
survey_template: document.getElementById('surveyTemplate').value, // Removed parseInt()
is_active: document.getElementById('isActive').checked
};
Technical Details
Why This Works
- The dropdown values now contain the full UUID strings
- These UUID strings are sent directly to the API as strings
- Django Rest Framework's
PrimaryKeyRelatedFieldaccepts UUID strings as valid identifiers - The serializer can successfully find the Hospital and SurveyTemplate objects by their UUID
UUID Format
UUIDs follow the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Example: 8ccecfba-ec98-446a-9d0f-61bf5b49bc8d
Serializer Compatibility
The SurveyTemplateMappingSerializer was already correct:
class SurveyTemplateMappingSerializer(serializers.ModelSerializer):
hospital_name = serializers.CharField(source='hospital.name', read_only=True)
survey_template_name = serializers.CharField(source='survey_template.name', read_only=True)
patient_type_display = serializers.CharField(source='get_patient_type_display', read_only=True)
class Meta:
model = SurveyTemplateMapping
fields = [
'id', 'hospital', 'hospital_name',
'patient_type', 'patient_type_display',
'survey_template', 'survey_template_name',
'is_active',
'created_at', 'updated_at'
]
Verification
The fix has been applied and the survey mapping functionality should now work correctly:
- Create Mapping: Users can now create new survey template mappings
- Edit Mapping: Users can edit existing mappings
- Delete Mapping: Delete functionality remains unchanged
- Cascading Dropdowns: Hospital selection still filters survey templates correctly
Testing Recommendations
To verify the fix works:
- Navigate to the Survey Mapping Settings page
- Click "Add Mapping"
- Select a hospital from the dropdown
- Select a survey template from the filtered dropdown
- Select a patient type
- Click "Save Mapping"
- Verify the mapping is saved successfully without validation errors
Files Modified
templates/integrations/survey_mapping_settings.html- Removed parseInt() calls
Related Files (No Changes Required)
apps/integrations/serializers.py- Already correctapps/integrations/models.py- Already correctapps/integrations/views.py- Already correct
Summary
This was a simple but critical bug where JavaScript was incorrectly parsing UUID strings as integers, causing validation errors when creating or editing survey template mappings. The fix ensures that UUID values are sent as strings to the API, which is the correct format for Django's UUID primary key fields.