'Can someone help me optimize my Django queries/project structure?

I have created a new Django project and it works fine, but I'm sure there is a better way to do the following and thought of asking.

So my main issue is on the template where I have to call the same for loop twice. The one time to include a clinic of the url as you can see on the urls.py, and the other time to show the rest of clinics that are available in the same day.

urls.py

path('onhold-hospitals/<slug:region_slug>/<slug:clinic_slug>/results/<yyyy:date>/', views.onhold_hospital_results, name='date-clinics-view-results')

I'm using this statement in the template:

{% for hospital in available_hospitals %}
    {% if hospital.onhold_date|date == default_date|date and hospital.clinic == clinic%}
        <h5>Name: {{ hospital.hospital}} - Name: {{ hospital.onhold_date}} - Clinic: {{ hospital.clinic}}</h5>
    {% endif %}
{% if hospital.onhold_date|date == default_date|date and hospital.clinic != clinic%}
    <p>Other clinics available on the same day: 
        {% for hospital in available_hospitals %}
            {{hospital.clinic}}
        {% endfor %}
{% endif %}
{% endfor %}

And here are my core model:

class Schedule(models.Model):
    onhold_hour = models.CharField(max_length=50, blank=True, null=True)
    onhold_date = models.DateField(default=date.today)
    region = models.ForeignKey(Region, on_delete=models.CASCADE, null=True, related_name="area")
    hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, null=True, related_name="available_hospital")
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE, null=True, related_name="clinic_type")

all these are being returned from the following views.py:

def onhold_hospital_results(request, region_slug, clinic_slug, **date_filters):
    clinic = Clinic.objects.get(slug=clinic_slug)
    region = Region.objects.get(slug=region_slug)
    get_clinics_id = Clinic.objects.get(slug = clinic_slug).id
    get_region_id = Region.objects.get(slug = region_slug).id
    default_date = today
    recent_dates = Schedule.objects.order_by('onhold_date').distinct('onhold_date').filter(onhold_date__range = (today, date_range), region = get_region_id)
    date_filters = recent_dates
    available_hospitals = Schedule.objects.filter(region = get_region_id, onhold_date=date)
    return render(request, 'hospitals_core/onhold_hospital_results.html', {
        'available_hospitals': available_hospitals,
        'region': region,
        'clinic': clinic,
        'date_filters': date_filters,
        'region_slug': region_slug,
        'default_date': default_date,
        'clinic_slug': clinic_slug
    })


Solution 1:[1]

You should filter in the view, not in the template, and with .select_related(…) [Django-doc], you can fetch the related hospitals:

def onhold_hospital_results(request, region_slug, clinic_slug, **date_filters):
    clinic = Clinic.objects.get(slug=clinic_slug)
    region = Region.objects.get(slug=region_slug)
    default_date = today
    recent_dates = Schedule.objects.order_by('onhold_date').distinct('onhold_date').filter(onhold_date__range = (today, date_range), region=region)
    date_filters = recent_dates
    available_hospitals = Schedule.objects.filter(
        region=region, onhold_date=default_date
    ).select_related('clinic', 'hospital')
    return render(request, 'hospitals_core/onhold_hospital_results.html', {
        'available_hospitals': available_hospitals,
        'region': region,
        'clinic': clinic,
        'date_filters': date_filters,
        'region_slug': region_slug,
        'default_date': default_date,
        'clinic_slug': clinic_slug
    })

The nested {% for hospital in available_hospitals %} also does not seem to make much sense: the outer loop already enumerates over the hospitals.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Willem Van Onsem