I have lot of models that are referring to each other in some way, for example:
Port is referring to City, which in its turn refers to Country. Then in django admin I want to show in list_display Ports country:
class Country(models.Model):
title = models.CharField()
class City(models.Model):
title = models.CharField()
country = models.ForeignKey(Country)
class Port(models.Model):
city = models.ForeignKey(City)
def __str__(self):
return self.city.county.title
So basically for each port django is generating more queries. I assume that select_related
would help me somehow in this case, but how to use it properly within the model?
In Django, select_related and prefetch_related are designed to stop the deluge of database queries that are caused by accessing related objects. In this article, we will see how it reduces the number of queries and make the program much faster.
The __str__() method is called whenever you call str() on an object. Django uses str(obj) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.
You can create a PortManager
class and override get_queryset
method and reference it in the model:
class PortManager(models.Manager):
def get_queryset(self):
return super(PortManager, self).get_queryset().select_related()
class Port(models.Model):
city = models.ForeignKey(City)
objects = PortManager()
def __str__(self):
return self.city.country.title
Based on Ivan's answer, I came up with the following structure for multiple models related with "one to many" and "many to many" relations using select_related
and prefetch_related
accordingly.
In the provided example only select_related
is required.
class Country(models.Model):
title = models.CharField()
def __str__(self):
return '{0}'.format(self.title)
class CityManager(models.Manager):
def get_queryset(self):
return super().get_queryset().select_related('country')
class City(models.Model):
title = models.CharField()
country = models.ForeignKey(Country)
objects = CityManager()
def __str__(self):
return '{0}-{1}'.format(
self.title,
self.country.__str__(),
)
class PortManager(models.Manager):
def get_queryset(self):
return super().get_queryset().select_related('city')
class Port(models.Model):
city = models.ForeignKey(City)
objects = PortManager()
def __str__(self):
return self.city.__str__()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With