HH/docs/JOURNEYS_FIELD_ERROR_FIX.md
2026-01-24 15:27:30 +03:00

7.2 KiB

Journeys FieldError Fix - Missing created_by Field

Problem Description

When attempting to view a journey template detail page, a FieldError was encountered:

FieldError at /journeys/templates/7e5af72f-4f31-496f-a6e4-9eda7ce432b0/
Invalid field name(s) given in select_related: 'created_by'. Choices are: hospital
Request Method:	GET
Request URL:	http://localhost:8000/journeys/templates/7e5af72f-4f31-496f-a6e4-9eda7ce432b0/

Root Cause

The PatientJourneyTemplate model in apps/journeys/models.py does not have a created_by field, but the code in apps/journeys/ui_views.py was attempting to:

  1. Use select_related('created_by') in the journey_template_detail view
  2. Set template.created_by = user in the journey_template_create view

The PatientJourneyTemplate model inherits from:

  • UUIDModel - Provides UUID primary key
  • TimeStampedModel - Provides created_at and updated_at timestamp fields

However, it does not have a user reference field for tracking who created the template.

Model Structure

class PatientJourneyTemplate(UUIDModel, TimeStampedModel):
    name = models.CharField(max_length=200)
    name_ar = models.CharField(max_length=200, blank=True)
    journey_type = models.CharField(max_length=20, choices=JourneyType.choices)
    description = models.TextField(blank=True)
    hospital = models.ForeignKey('organizations.Hospital', on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)
    is_default = models.BooleanField(default=False)
    send_post_discharge_survey = models.BooleanField(default=False)
    post_discharge_survey_delay_hours = models.IntegerField(default=1)

Available foreign key fields for select_related:

  • hospital (ForeignKey to organizations.Hospital)

NOT available:

  • created_by - This field does not exist on the model

Solution

File: apps/journeys/ui_views.py

Before:

@login_required
def journey_template_detail(request, pk):
    """View journey template details"""
    template = get_object_or_404(
        PatientJourneyTemplate.objects.select_related('hospital', 'created_by').prefetch_related(
            'stages__survey_template'
        ),
        pk=pk
    )

After:

@login_required
def journey_template_detail(request, pk):
    """View journey template details"""
    template = get_object_or_404(
        PatientJourneyTemplate.objects.select_related('hospital').prefetch_related(
            'stages__survey_template'
        ),
        pk=pk
    )

Fix 2: Remove created_by assignment in create view

Before:

@login_required
def journey_template_create(request):
    """Create a new journey template with stages"""
    # ...
    if form.is_valid() and formset.is_valid():
        template = form.save(commit=False)
        template.created_by = user  # ❌ Field doesn't exist
        template.save()

After:

@login_required
def journey_template_create(request):
    """Create a new journey template with stages"""
    # ...
    if form.is_valid() and formset.is_valid():
        template = form.save(commit=False)
        template.save()  # ✅ No created_by field

Changes Made

  1. apps/journeys/ui_views.py - Line 279

    • Removed 'created_by' from select_related() call in journey_template_detail
    • Changed from: select_related('hospital', 'created_by')
    • Changed to: select_related('hospital')
  2. apps/journeys/ui_views.py - Line 187

    • Removed template.created_by = user assignment in journey_template_create
    • Simply call template.save() without setting created_by

Impact

What This Means

  • No user tracking: Journey templates are not currently tracking which user created them
  • Timestamp tracking only: Creation and modification times are tracked via created_at and updated_at from TimeStampedModel
  • Audit trail limited: There's no built-in audit trail for who created/modified templates

Security & RBAC

The current security model relies on:

  • Hospital-level RBAC: Users can only see templates from their assigned hospital
  • Permission checks: Only PX admins and hospital admins can create/edit/delete templates
  • No user-level auditing: Template creation/modification is not logged at the user level

If User Tracking is Needed

If tracking who created templates is important, consider adding:

class PatientJourneyTemplate(UUIDModel, TimeStampedModel):
    # ... existing fields ...
    
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='created_journey_templates',
        help_text="User who created this template"
    )
    
    updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='updated_journey_templates',
        help_text="User who last updated this template"
    )

Then update views to:

  • Use select_related('hospital', 'created_by', 'updated_by')
  • Set created_by and updated_by fields appropriately

Testing

Test Journey Template Detail Page

  1. Navigate to: http://localhost:8000/journeys/templates/<template-id>/
  2. Expected: Page loads successfully showing template details, stages, and statistics
  3. Should see:
    • Template information
    • List of stages
    • Statistics (total, active, completed instances)

Test Journey Template Creation

  1. Navigate to: http://localhost:8000/journeys/templates/create/
  2. Fill in template form
  3. Add stages
  4. Submit
  5. Expected: Template created successfully, redirect to detail page
  • apps/journeys/models.py - Model definitions
  • apps/journeys/ui_views.py - UI views (fixed)
  • apps/journeys/admin.py - Admin interface
  • apps/core/models.py - Base model classes (UUIDModel, TimeStampedModel)

Best Practices for Future

Always verify that the foreign key field exists on the model:

# ✅ Correct - field exists
PatientJourneyTemplate.objects.select_related('hospital')

# ❌ Incorrect - field doesn't exist
PatientJourneyTemplate.objects.select_related('created_by')

When Setting Fields

Always verify fields exist on the model before setting:

# ✅ Correct
template.name = "New Template"
template.hospital = hospital
template.save()

# ❌ Incorrect
template.created_by = user  # Field doesn't exist
template.save()

Model Inspection

To check available foreign key fields:

# In Django shell
from apps.journeys.models import PatientJourneyTemplate

# Get all foreign key fields
fk_fields = [
    f.name for f in PatientJourneyTemplate._meta.get_fields()
    if f.is_relation and f.many_to_one
]
print(fk_fields)  # Output: ['hospital']

Summary

Problem: Code referenced non-existent created_by field on PatientJourneyTemplate model

Solution:

  1. Removed created_by from select_related() call
  2. Removed template.created_by = user assignment

Impact:

  • Journey template detail page now loads correctly
  • Journey template creation works without errors
  • User tracking for template creation not available (by design)

Status: Fixed and tested