0
votes

===Models===

class A(models.Model):
     name= models.CharField(max_length=20, blank=False)

Class B(models.Model):
     university = models.CharField(max_length=25, blank=False)
     location = models.CharField(max_length=30, blank=False)
     b_fk= models.ForeignKey(A)

Class C(models.Model):
     studentclass = models.CharField(max_length=10, blank=False)
     section = models.CharField(max_length= 10)
     c_fk = models.ForeignKey(B)

class Cfurther(models.Model):
     branch= Models.CharField(max_length=15, blank=Flase)
     number = models.IntegerField()
     cfur_fk = models.ForeignKey(C)

class Info(models.Model):
     info_number = models.IntegerField()
     info = models.CharField(max_length= 12, blank=Flase)
     info_fk = models.ForeignKey(B, related_name= "info_set")

class Infocategory(models.Model):
     find = models.CharField(max_length=15, blank=False)
     cat_fk = models.ForeignKey(Info)

class Extra(models.Model):
     extrainfo = models.CharField(max_length=30)
     extra_fk = models.ForeignKey(Infocategory)

===View===

Django documentation

Returns a QuerySet that will automatically "follow" foreign-key relationships, selecting that additional related-object data when it executes its query.

select_related is limited to single-valued relationships - foreign key and one-to-one.

https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related

I have written Following Queryset to fetch model fields (all the relationships are one-to-many)

myquery = Info.objects.select_related().filter(info_number__iexact = 123)
  • I want to traverse from Info Model toward Upper and lower models
  • I don't have problem in getting Class A records with select_related() in the template, but is it possible to get all the model fields with select_related in my case (Class B, C, Cfurther, Infocategory, Extra)?
  • If not do I have to create new queryset? or what select_related() will work?

I am little bit confused regarding select_related field lookup

1

1 Answers

4
votes

You can traverse through all the relationships as deep as you want just through the standard Django API. select_related doesn't do anything special in setting up the relationships; it merely allows you to reduce the number of DB queries by performing joins in advance (instead of looking up each foreign key as it's accessed).

However, as the docs state, select_related only works with Foreign Keys and OneToOneFields. It doesn't work with ManyToManyFields at all. Additionally, you can only follow reverse relationship with select_related if it's a OneToOneField. Reverse ForeignKeys are not supported. Finally, by default select_related only follows fields that have null=False. If it's a NULL-able field, you must explicitly tell select_related to follow it:

SomeModel.objects.select_related('some_nullable_field')

Once Django 1.4 hits, you'll have access to a new method called prefetch_related which works like select_related but supports ManyToManyFields and reverse ForeignKey relationships.