jeffa.david
jeffa.david

Reputation: 45

django templates loop two querysets

I am trying to get details of two querysets and display on my datatable. I can display details of first queryset but not of the second which is also dependent on the first queryset.

My views.py function;

def truck_list(request):
   q_data = quar_contacts.objects.all().filter(.....)
   hot_details = []
   for d in q_data:
      h_details = truck_contacts.objects.filter(p_contacts=d.id)        
      hot_details.append(h_details)

   my_list_data = zip(q_data, hot_details)
   data = {'quar_data': my_list_data}

   return render(request, 'syst/truck_list.html', data)

I can print out details of the zip list as a tuple i.e data = tuple(my_list_data) and see the data.

Then my truck_list template on the datatable body section :

  <tbody>
    {% for q_data, hot_details in quar_data %}
        <tr>
           <td>{{ q_data.last_name }}</td>
           <td>{{ q_data.first_name }}</td>
           <td>{{ q_data.age }}</td>
           <td>{{ q_data.sex }}</td>
           <td>{{ q_data.phone_number }}</td>
           <td>{{ hot_details.hotel_name}}</td>                 
           <td>{{ hot_details.date_check_in }}</td>
           <td>{{ hot_details.created_by }}</td>
        </tr>
    {% endfor %}
   </tbody>

How can i get the hot_details (hotel_name and date_checked_in) displayed on my datatable. How can I loop for each contact what hotel details are there.

Is there an easier way of achieving this?

My Models:

class quar_contacts(models.Model):

    first_name = models.CharField(max_length=50)
    middle_name = models.CharField(max_length=50, blank=True)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=50)
    dob = models.DateField(default=date.today)
    passport_number = models.CharField(max_length=50, blank=True)
    created_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name='quar_updated_by')

class truck_contacts(models.Model):

    patient_contacts = models.ForeignKey(quar_contacts, on_delete=models.DO_NOTHING, related_name='truck_contact')
    vehicle_registration = models.CharField(max_length=50, blank=True)
    company_name = models.CharField(max_length=50, blank=True)
    hotel = models.CharField(max_length=50, blank=True)
    hotel_town = models.CharField(max_length=50, blank=True)
    date_check_in = models.DateField(default=date.today)
    date_check_out = models.DateField(default=date.today)

Also, how do you get the 'created_by' value which is a foreign key of the Users table?

Upvotes: 0

Views: 322

Answers (2)

jeffa.david
jeffa.david

Reputation: 45

Using "annotate" I have managed to to add the fields the other way. getting 'truck_contacts' queryset then look for the parent field values 'quar_contacts'. Thanks to @rafaljusiak idea above.

all_data = truck_contacts.objects.all().annotate(
        first_name=F("patient_contacts__first_name"),
        last_name=F("patient_contacts__last_name"),
        sex=F("patient_contacts__sex"),
        age=F("patient_contacts__dob"),
        passport_number=F("patient_contacts__passport_number"),
        phone_number=F("patient_contacts__phone_number"),
        created_by=F("patient_contacts__created_by"),
    )

But am still struggling how to display 'created by' being a foreign key of Users table

Upvotes: 0

rafaljusiak
rafaljusiak

Reputation: 1090

You can use annotate to add additional fields to each object from quar_contacts queryset. I don't know your db schema, but if "quar contact" has a foreign key to "truck contact" it can be something like that:

from django.db.models import F

q_data = quar_contacts.objects.all().filter(.....).annotate(
    hotel_name=F("your_relation_name__hotel_name"),
    date_check_in=F("your_relation_name__date_check_in"),
)

Then you can access hotel_name and date_check_in just like other fields from this objects.

Please let me know if it's helpful. If you have different relation between those models I'll update my answer.

Upvotes: 1

Related Questions