Anoop K George
Anoop K George

Reputation: 1735

Django,referring objects with double underscore

I have a function in the view file of Django Rest Framework project. Where it filters out comments (A model) with related to the specific Post

 class CommentListCreate(APIView):
    def get(self, request,pk):
        comment = Comment.objects.filter(post_id=pk)
        serializer = CommentSerializers(comment, many=True)
        return Response(serializer.data)   

The above function is able to filter according to the post_id, but if I change filter arguments as mention below

 def get(self, request,pk):
        comment = Comment.objects.filter(post__id=pk)

The function works fine, why do we use double underscore to refer the the post id ?

Git Link to my views.py https://github.com/Anoop-George/DjangoBlog/blob/master/blog/views.py

Upvotes: 1

Views: 3217

Answers (2)

tim-mccurrach
tim-mccurrach

Reputation: 6815

We use a double underscore to refer to the property of some related object in a django query. You can think of it in a similar way, to how you would think of a dot, chaining together properties.

Suppose I have the following models:

class Car(models.Model):
    ...

    engine = models.ForeignKey('Engine', ...)

class Engine(models.Model):
    ...
    engine_size = models.IntegerField()
    engine_make = models.ForeignKey('EngineMake', ...)

class EngineMake(models.Model):
    company_name = models.CharField()

Now if I wanted to filter to find all cars with an engine made by a particular company, to go through the related fields, I can use a double underscore, such as follows:

cars = Car.objects.filter(engine__engine_make__company_name="something")

In your case, you don't really need a double underscore, as when you add a ForeignKey, Django automatically adds a field called foo_id, if you add a foreign key called foo for example.

Upvotes: 3

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476719

If it is a ForeignKey, you can use both. The first post_id is the "twin field" Django makes for a ForeignKey (this has a name with an _id suffix), and stores the value of the primary key of the record it refers to (or another unique field if you specify that in the to_field parameter).

If you want to look "through" a relation, you use double underscores (__). So you can refer to it with post__id as well.

If you however want to filter based on the title of the Post object, you query with:

comment = Comment.objects.filter(post__title='some title')

You can not use a single underscores, since a ForeignKey only makes a twin-field to store a reference, it does not make a post_title field to store the title of the referred Post object (that would not be a good idea, since it introduces data duplication).

Upvotes: 1

Related Questions