HH/SURVEY_FORM_ATTRIBUTE_ERROR_FIX.md
2026-02-22 08:35:53 +03:00

4.2 KiB

Survey Form AttributeError Fix

Problem

When accessing /surveys/send/, the application threw an AttributeError: 'User' object has no attribute 'get'.

Error Details

AttributeError at /surveys/send/
'User' object has no attribute 'get'
Request Method: GET
Request URL: http://localhost:8000/surveys/send/
Exception Location: /home/ismail/projects/HH/.venv/lib/python3.12/site-packages/django/utils/functional.py, line 253, in inner
Raised during: apps.surveys.ui_views.manual_survey_send

The error occurred during template rendering at line 93 of templates/surveys/manual_send.html.

Root Cause

The forms ManualSurveySendForm, ManualPhoneSurveySendForm, and BulkCSVSurveySendForm were being instantiated with a user parameter in the view:

form = ManualSurveySendForm(user)  # In manual_survey_send view
form = ManualPhoneSurveySendForm(user)  # In manual_survey_send_phone view
form = BulkCSVSurveySendForm(user)  # In manual_survey_send_csv view

However, these forms did not have custom __init__ methods to accept the user parameter. When Django tried to pass the user object as the first positional argument, the form's default __init__ method expected a dictionary-like object (data) but received a User object instead.

Solution

Added custom __init__ methods to all three forms that:

  1. Accept a user parameter as the first argument
  2. Call the parent class's __init__ method correctly
  3. Store the user object for potential later use
  4. Filter the survey_template queryset to show only templates from the user's hospital

Changes Made to apps/surveys/forms.py

1. ManualSurveySendForm

class ManualSurveySendForm(forms.Form):
    """Form for manually sending surveys to patients or staff"""
    
    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user
        # Filter survey templates by user's hospital
        if user.hospital:
            self.fields['survey_template'].queryset = SurveyTemplate.objects.filter(
                hospital=user.hospital,
                is_active=True
            )
    
    # ... rest of the form fields

2. ManualPhoneSurveySendForm

class ManualPhoneSurveySendForm(forms.Form):
    """Form for sending surveys to a manually entered phone number"""
    
    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user
        # Filter survey templates by user's hospital
        if user.hospital:
            self.fields['survey_template'].queryset = SurveyTemplate.objects.filter(
                hospital=user.hospital,
                is_active=True
            )
    
    # ... rest of the form fields

3. BulkCSVSurveySendForm

class BulkCSVSurveySendForm(forms.Form):
    """Form for bulk sending surveys via CSV upload"""
    
    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user
        # Filter survey templates by user's hospital
        if user.hospital:
            self.fields['survey_template'].queryset = SurveyTemplate.objects.filter(
                hospital=user.hospital,
                is_active=True
            )
    
    # ... rest of the form fields

Note: BulkCSVSurveySendForm already had an __init__ method but it was defined after the field definition, which could cause issues. It's been moved before the field definitions for consistency.

Benefits

  1. Fixes the AttributeError: Forms can now be instantiated with a user parameter
  2. Improved Security: Survey templates are filtered by the user's hospital, preventing users from seeing templates they shouldn't have access to
  3. Better User Experience: Users only see relevant survey templates in the dropdown
  4. Consistency: All three manual survey send forms now have the same initialization pattern

Testing

To verify the fix:

  1. Navigate to /surveys/send/
  2. The page should load without errors
  3. The survey template dropdown should only show templates from the user's hospital
  4. Test the phone-based survey send at /surveys/send/phone/
  5. Test the CSV-based bulk send at /surveys/send/csv/

All three views should now work correctly.