django db_index for foreign key reverse lookup

  • Last Update :
  • Techknowledgy :

Let's say the you have a simple model structure:

class Author(models.Model):
   name = models.CharField(max_length = 70)
email = models.EmailField()

class Book(models.Model):
   title = models.CharField(max_length = 100)
author = models.ForeignKey(Author)

Now querying:

author_books = Book.objects.filter(author = a)

or

author_books = a.book_set.all()

Suggestion : 2

For fields like ForeignKey that map to model instances, defaults should be the value of the field they reference (pk unless to_field is set) instead of model instances.,Set this to the name of a DateField or DateTimeField to require that this field be unique for the value of the date field.,The default value is used when new model instances are created and a value isn’t provided for the field. When the field is a primary key, the default is also used when the field is set to None.,It should return the value of the appropriate attribute from model_instance for this field. The attribute name is in self.attname (this is set up by Field).

YEAR_IN_SCHOOL_CHOICES = [
   ('FR', 'Freshman'),
   ('SO', 'Sophomore'),
   ('JR', 'Junior'),
   ('SR', 'Senior'),
   ('GR', 'Graduate'),
]
from django.db
import models

class Student(models.Model):
   FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
GRADUATE = 'GR'
YEAR_IN_SCHOOL_CHOICES = [
   (FRESHMAN, 'Freshman'),
   (SOPHOMORE, 'Sophomore'),
   (JUNIOR, 'Junior'),
   (SENIOR, 'Senior'),
   (GRADUATE, 'Graduate'),
]
year_in_school = models.CharField(
   max_length = 2,
   choices = YEAR_IN_SCHOOL_CHOICES,
   default = FRESHMAN,
)

def is_upperclass(self):
   return self.year_in_school in {
      self.JUNIOR,
      self.SENIOR
   }
MEDIA_CHOICES = [
   ('Audio', (
      ('vinyl', 'Vinyl'),
      ('cd', 'CD'),
   )),
   ('Video', (
      ('vhs', 'VHS Tape'),
      ('dvd', 'DVD'),
   )),
   ('unknown', 'Unknown'),
]
from django.utils.translation
import gettext_lazy as _

class Student(models.Model):

   class YearInSchool(models.TextChoices):
   FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')

year_in_school = models.CharField(
   max_length = 2,
   choices = YearInSchool.choices,
   default = YearInSchool.FRESHMAN,
)

def is_upperclass(self):
   return self.year_in_school in {
      self.YearInSchool.JUNIOR,
      self.YearInSchool.SENIOR,
   }
>>> class Vehicle(models.TextChoices):
   ...CAR = 'C'
   ...TRUCK = 'T'
   ...JET_SKI = 'J'
   ...
   >>>
   Vehicle.JET_SKI.label 'Jet Ski'
class Card(models.Model):

   class Suit(models.IntegerChoices):
   DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4

suit = models.IntegerField(choices = Suit.choices)

Suggestion : 3

Currently reverse ForeignKey lookups are impossible for models which are related to other models more than once. Could this be fixed by using the related_name instead of the model's name for resolving the one-to-many lookup? , On a related note: It seems inconsistent to me that two ForeignKeys related to the same model result in a reverse lookup exception but, e.g., a ForeignKey and a ManyToMany-Field related to the same model don't raise the "TypeError: Can't resolve keyword" exception (the ManyToManyField is used, the ForeignKey ignored). , This seems to work in the current version of magic-removal, great! I have attached the unit tests that demonstrate that it works (and make sure it doesn't break). , (In [2280]) magic-removal: Fixed #1305 -- Added new unit test group for reverse lookup queries over foreign keys. Thanks, Andreas.

Currently reverse ForeignKey lookups are impossible for models which are related to other models more than once. Could this be fixed by using the related_name instead of the model's name for resolving the one-to-many lookup?

class Poll(models.Model):
   question = models.CharField(maxlength = 200)

class Choice(models.Model):
   name = models.CharField(maxlength = 100)
poll = models.ForeignKey(Poll, related_name = "choice")
related_poll = models.ForeignKey(Poll, related_name = "related_choice")
class Poll(models.Model):
    question = models.CharField(maxlength=200)

class Choice(models.Model):
    name = models.CharField(maxlength=100)
    poll = models.ForeignKey(Poll, related_name="choice")
    related_poll = models.ForeignKey(Poll, related_name="related_choice")
first_poll = Poll(question = "What's the first question?")
first_poll.save()
second_poll = Poll(question = "What's the second question?")
second_poll.save()
new_choice = Choice(
   poll = first_poll,
   related_poll = second_poll,
   name = "This is the answer."
)
new_choice.save()

# The current state:
   try:
   Poll.objects.get_object(choice__name__exact = "This is the answer.")
except TypeError:
   # raises TypeError with "Cannot resolve keyword 'choice' into field"
# because more than one field could be identified by "choice"
pass

# How it could be(lookups by related_name):
   Poll.objects.get_object(choice__name__exact = "This is the answer.") # returns first poll
Poll.objects.get_object(related_choice__name__exact = "This is the answer.") # returns second poll