When you have two models connected by a foreignkey in django do you need to do a join?

5k Views Asked by At

The Django docs are not plainly stating this and its getting annoying.

Observe the following models:

# models
class Venue(models.Model):
    name = models.CharField(max_length=150, blank=False)
    description = models.CharField(max_length=1000)
    image = models.ImageField(upload_to=imgUnique('venueMedia/venueImages'))
    streetAddress= models.CharField(max_length=100)
    city = models.CharField(max_length=100, blank=False)
    state = models.CharField(max_length=100, blank=False)


class Room(models.Model):
    name = models.CharField(max_length=150, blank=False)
    venue = models.ForeignKey(Venue, related_name='rooms', on_delete=models.CASCADE)
    description = models.CharField(max_length=1000)
    standingCapacity = models.IntegerField
    seatedCapacity = models.IntegerField
    image = models.ImageField(upload_to=imgUnique('venueMedia/venueImages'))

I have a foreign key relationship into Venue in the Room model in the rooms venue property.

Do I need to join those tables? Or will a Venue.objects.all() do that for me automatically? If not I have the raw sql as follows will this work:

 venueList = Venue.objects.raw('''SELECT *
                              FROM venue_Venue
                              INNER JOIN venue_Room
                              ON venue_Venue_id=venue_Room_id''')

if not that then I understand there is a select_related() method and my understanding is that I would do the following:

Venue.objects.all().select_related('Room') 

Can we get this clear? As you can see I have done alot of research but am still confused

1

There are 1 best solutions below

3
Arpit Solanki On BEST ANSWER

select_related

select_related can be used when you want to select the objects connected by ForeignKey or OneToOne field, more precisely you can use this only when you want to select a single connected object. select_related takes a param can use it to lookup for related_field. The param related_name='rooms' specified in your model attributes is responsible for setting related names. select_related method searches for these related names and if it finds a match then it returns you the related objects. This line

Venue.objects.all().select_related('Room')  

would result in a lookup error as you don't have any related names 'Room' but you have room so you also need to watch out for case sensitivity. Below one would work.

Venue.objects.all().select_related('room')

As mentioned above select_related can only be used for selecting single related objects. If you wish to fetch multiple related objects like for ManyToManyField then use prefetch_related