Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-filter

Nested Query / not directly related field in Django


If the models are as follows,

class Subject(BaseModel):
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)

    class Meta:
        managed = True
        db_table = 'Subject'


class Topic(BaseModel):
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE, null=False, related_name='subject_topic')

    class Meta:
        managed = True
        db_table = 'Topic'


class Question(BaseModel):
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE, null=False, related_name='question_topic')
    class Meta:
        managed = True
        db_table = 'Question'

How can I make a query Question for a subject.

questions = Question.objects.filter(topic_in=Topic.objects.get(subject=subject).only('id').all())

but it's not working. Any help would be really great help.


Solution

  • Your current "inner queryset" won't give you multiple values, it only returns 1.

    Topic.objects.get(subject=subject).only('id').all()
    

    You are using .objects.get() which returns a model instance, so for example .only() or .all() on that won't work unless your model has such a defined function.

    Furthermore you don't really need 2 querysets, you can get your result with only one:

    my_subject_ids = [...]  # these are the ids of Subject models you want
    Question.objects.filter(topic__subject_id__in=my_subject_ids)
    

    You can also query for Subject.name, just use the following for this: topic__subject__name__in=my_list.

    If you want to query for a specific Subject-instance you can use topic__subject=my_obj.

    You also might wanna take a look at the docs for more information on that.