I want to present a list of objects for which I want to filter/modify one attribute during the presentation of the data. Something close to an annotation, but I did not manage to do it with annotations. These are the models

class Airline (models.Model):
   name = models.CharField()
   destinations = models.ManyToManyField("city")
   customers = models.ManyToManyField("user")

class City (models.Model):
   name = models.CharField()
   country = models.CharField()
 
class User (models.Model):
   name = models.CharField()
   preferredDestinations = models.ManyToManyField("city")

I want, for a given user, present a list of the Airlines the user is customer, and for each Airline present the list of destinations for the Airline. But instead of presenting all the airline destinations I only want to present the destinations preferred by the user.

e,g,

Airline1.destinations=["New York", "London", "Paris", "Madrid]
Airline2.destinations=["Madrid", "Barcelona", "Rome", "Berlin", "London"]

User1.preferredDestinations=["Madrid", "Barcelona", "Paris"]

With user1 being a customer of Airline1 and Airline 2, I want the page to present a table showing to which of the user preferred destination every airline flies to. I.e. I do not want to see all the destinations the airline flies to, only the ones the user is interested: E.g.

Welcome User1!
These are your airlines that fly to your preferred destinations
Airline    | Destination |
| -------- | --------  |
| Airline1 | Madrid    |
|          | Paris     |
| -------- | --------  |
| Airline2 | Madrid    |
|          | Barcelona |

In the view I get a queryset for the user

airlineSet = Airline.objects.filter(customers=user.id)

And in the template

{% for airline in airlineSet %}
  <tr>
  <td>
   {{ airline.name }}
  </td>
  <td>
    {% for city in airline.destinations.all %}
    <li>
      {{ city }}
    </li>
    {% endfor %} 
  </td>
  </tr>
{% endfor %} 

This presents all the destinations for the airline, but I want a subset which is the intersection of airline.destinations and user.preferredDestinations

I tried to get the subset and put it in the attribute destination of the objects in the queryset airlineSet, but that actually modified the original Airline objects, and messed up the database.
I though of creating annotations in the queryset with the subset of the cities, but it seems it's limited what you can add with annotations (count, max, mix). I do not know how to add such annotations.

In addition, in the example above I put a few cities, but it actually can be a quite long number of cities, for the airline and for the user, and I want to limit how many cities are presented in the overview page to not over-flood with a big list of cities, but showing a short list (when I click on the airline it would show the whole union)

I made the intersection in the template {% if city in preferredDestinations %} but that has limitations for limiting the number of cities.

Is this something doable on the View?

1

There are 1 best solutions below

1
On

What you can do is

{% for airline in airlineSet %}
  <tr>
  <td>
   {{ airline.name }}
  </td>
  <td>
    {% for city in airline.destinations.all %}
    
      {% if city in user.preferredDestinations %}
        <li>
          {{ city }}
        </li>
      {% endif %}
    
    {% endfor %} 
  </td>
  </tr>
{% endfor %}

And not to show too many cities I would recommend using pagination.