Select only foreign key column and querry set

I have two models in django no foreign in tables:

class Airport(models.Model):
   ID = models.AutoField()
   Name = models.CharField()
   City = models.CharField()
   ICAO = models.CharField()

class Airport_Frequency(models.Model):
   TC_Type = models.CharField()
   Frequency_MHz = models.DecimalField()
   airport =  models.ForeignKey(Airport, on_delete=models.PROTECT, null= True, blank=True)

How can I Select only foreign key column only and use distinct() function to get only unique field from Airport_Frequency an then reference by it show only Name and ICAO (based on foreign key relation).

I was traying to override a query :

def get_queryset(self):
   # original qs
   qs = Airport_Frequency.objects.all()
   return qs.only('airport').distinct() 

2.) If I’m workin on a shell how can I get all data in the <QuerySet [<Airport_Frequency: Airport_Frequency object (13)>,…> for example list all what is in the Airport_Frequency: Airport_Frequency object (13).

#1 - Add the ‘airport’ field name in your distinct clause.
qs.only('airport').distinct('airport')

#2 - You can reference the fields within the model as any other attribute. For instance, if airport_frequency is an instance of the Airport_Frequency model, then airport_frequency.TC_Type is the TC_Type field for that instance.

#1 - thanks
#2 - if I knows the fields that were selected SQL - but can i see paricular object data in shell like the querry str(qs.query) for example?

Yes, exactly the same way you access that data in your views.

Hi
Unfortunatly gettin an error while workin with MySql:

operations.py", line 176, in distinct_sql
raise NotSupportedError(‘DISTINCT ON fields is not supported by this database backend’)
django.db.utils.NotSupportedError: DISTINCT ON fields is not supported by this database backend

is there any walkaround?

Wow, didn’t know MySql didn’t support that. My first reaction would be something like this:
qs.values_list('airport', flat=True).distinct()
will give you a list of just the primary key values for the Airport instances in your Airport_Frequency queryset.

If you want the actual Airport instances, you could do something like this:

airport_list = qs.values_list('airport', flat=True).distinct()
airports = Airport.objects.filter(id__in=airport_list)

(There likely are different ways of doing this - this was my first thought.)

By meaning of usage of Generic views if I have a model:

 class Airport_Frequency(models.Model):

view

 class Airport_FrequencyListView(ListView):

then in the template i cen refer to object_list or airport_frequency_list.

but why when i override a querry as we discussed and add it to exisying view:

class Airport_FrequencyListView(ListView):

def get_queryset(self):
   airport_list_id = Airport_Frequency.objects.values_list('airport', flat=True).distinct()
   return Airport.objects.filter(ID__in = airport_list_id)

then i can only refer to filtered data by object_list. To redefine it get_context_data function is used?

What’s happening here is that you’re changing the type of data being returned by get_queryset.

If your Airport_FrequencyListView is supposed to be a list of Airport_Frequency, then that’s what get_queryset is supposed to return. (You don’t show here what model is associated with Airport_FrequencyListView - if one is even defined.)
However, what you’re returning from get_queryset is a set of Airport objects - a different model entirely.
You should be able to refer to that data in your template as airport_list.

The model assiociated with Airport_Frequency class is Airport_Frequency from th 1-st post (your assumption is correct).

class Airport_FrequencyListView(ListView):
    model = Airport_Frequency

What if more then one model is in query… How it will be named then … By default object_list or combinantion of model names in query. What django algorytm will do… How it will be conatenated…

A queryset returns one model. There may be associated models through foreign key relationships, but there’s always just one base model being referenced - it’s the model for which the manager is being used.

Using the default objects manager, Airport_Frequency.objects.<whatever> is going to return Airport_Frequency objects. Likewise, Airport.objects.<whatever> is going to give a queryset returning Airport objects.

Agree and as you mentioned.
In template I can use object_list or airport_list throughout I can itarate. The same with Airport_Frequency I can use object_list or airport_frequency_list.

But in case of template for frequency list when I used airport_frequency_list I get nothing (no items) but when I iterate throughout object_list html was populated with data.
What is an issue here

I would need to see the relevant view here. I’m not sure if you’re referring to some code you’ve already posted or yet a different issue.

class Airport_FrequencyListView(ListView):

 model = Airport_Frequency
     paginate_by = 18
     template_name = 'freq_list.html'

def get_queryset(self):
   airport_list_id = Airport_Frequency.objects.values_list('airport', flat=True).distinct()
   return Airport.objects.filter(ID__in = airport_list_id)

This is what I was referring to in my previous reply.

But why I couldn’t use the airport_frequency_list object name which should be equal to object_list when creating a html file

 {% for airportfrequency in object_list %}
    ....
  {% endfor %}

returns the objects while

{% for airportfrequency in airport_frequency _list %}
    ....
  {% endfor %}

this html code refers to the Airport_FrequencyListView(ListView) class.

No, the reference is not to the view class. It’s to the data in the context being supplied to the template. The view class name is not relevant.

Again, from my previous reply, get_queryset is not returning objects of type Airport_Frequency, it’s returning objects of type Airport.

Ok, understood, so in general due to the fact that it returns an Airport model it will also use the def get_absolute_url(self) and other functions from the Airport model instead the ones defined in Airport_Frequency model

If the above statement is True how to then get absolute url to specific Airport frequency fields , if the we know that Airport ID field is the foreign key in th Aifport_Frequency. in other way if I have an airport_list_id ppicking the specific id from that list it will bring the arirport frequency model details for that id

I don’t know what the it is that you’re referring to here. If you’re referring to a call to get_absolute_url on an instance of Airport, then yes, it’s the Airport’s get_absolute_url method to be called.

Accessing data across Foreign Key relationships is documented in the Related Object Reference page.

So , let me be more precise,

Having a models defined as follow:
models.py

class Airport(models.Model):
   ID = models.AutoField()
   Name = models.CharField()
   City = models.CharField()
   ICAO = models.CharField()

  def get_absolute_url(self):
    return reverse('airports:airport-detail', args=[str(self.pk)])

class Airport_Frequency(models.Model):
   TC_Type = models.CharField()
   Frequency_MHz = models.DecimalField()
   airport =  models.ForeignKey(Airport, on_delete=models.PROTECT, null= True, blank=True)

   def get_absolute_url(self):
      return reverse("airports:frequency-detail", kwargs={"pk": self.pk})

Views.py

class AirportListView(ListView):
    model = Airport

class AirportDetailView(DetailView):
    model = Airport

class Airport_FrequencyListView(ListView):
    model = Airport_Frequency
    paginate_by = 18
    template_name = 'air_freq_list.html'

    def get_queryset(self):
       airport_list_id = Airport_Frequency.objects.values_list('airport', flat=True).distinct()
       return Airport.objects.filter(ID__in = airport_list_id)

class Airport_FrequencyDetailView(DetailView):
    model = Airport_Frequency
    template_name = 'air_freq__detail.html'

So opening air_freq_list.html page get_queryset from Airport_FrequencyListView is called. What we get from custom querry is airport object url (we are switching the model - “we are in” the Airports model). Then get_absolute_url is also the one which belongs to Airport model.py not the one from the Airport_Frequency, resulting airport detail list view instead of air_freq__detail.

The questions are then :
#1 - how to force django to get correct url redirecting to air_freq__detail.html.
#2 - what will heppen when we will have in the custom get_queryset data from more than two modeles
#3 - refering to naming why django change the model to airports as you mention due to custom query in Airport_FrequencyListView, if this is only a query that selects the data (objects)- it is only an sql querry with data…

the this solution became much sofisticated then simple SQL query

 SELECT DISTINCT a.ICAO, b.ICAO, b.Name FROM airport as b, airport_frequency as a WHERE a.ICAO = b.ICAO

No, this is not an accurate statement to make. We’re not “in” anything other than a view.
Briefly, the get_context_data method gets the model name from the queryset returned by get_queryset, and adds an entry to the context based on that name - in addition to setting the key ‘object’ to that same data set.

You’re always calling get_absolute_url on an instance of an object, it doesn’t matter what the object type is.

If you read the source for the generic CBVs, you’ll get a better understanding of what’s going on here. (The Classy Class-Based View site along with the Class Based View diagram site are excellent aids for understanding how they work.)

This addresses your question #3.

#2 I’ve addressed before. The get_queryset method returns one queryset, which has one base model. Other, related data, is accessed through the related fields. It makes no sense to think of a get_queryset returning multiple querysets from different models. (This may require an adjustment of your “mental model” regarding how these CBVs work and what you’re trying to accomplish.)

To answer #1, I would need to know whether the relationship between Airport and Airport_Frequency is truly a one-to-many (One Airport may have many Airport_Frequency objects related to it) or if it’s actually a one-to-one (Each Airport only has one Airport_Frequency assigned to it. If so, then Airport_Frequency really should be defined as a OneToOne Field instead of a ForeignKey field.)

It’s also going to help me a lot if I can understand what your final objective is. What do you want on this page?

I’m assuming you want a page showing a List of things. What is this to be a list of? (Airport, or Airport_Frequency?)
For each entry in this list, what data do you want displayed?
You’ve commented a couple times on get_absolute_url - what do you want the URL for? (I’m guessing a detailed page for either Airport or Airport_Frequency, which one?)