Query intermediate through fields in django


I have a simple Relation model, where a user can follow a tag just like stackoverflow.

class Relation(models.Model):
    user = AutoOneToOneField(User)
    follows_tag = models.ManyToManyField(Tag, blank=True, null=True, through='TagRelation')

class TagRelation(models.Model):
    user = models.ForeignKey(Relation, on_delete=models.CASCADE)
    following_tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
    pub_date = models.DateTimeField(default=timezone.now)

    class Meta:
        unique_together = ['user', 'following_tag']

Now, to get the results of all the tags a user is following:

kakar = CustomUser.objects.get(email="kakar@gmail.com")
tags_following = kakar.relation.follows_tag.all()

This is fine.

But, to access intermediate fields I have to go through a big list of other queries. Suppose I want to display when the user started following a tag, I will have to do something like this:

kakar = CustomUser.objects.get(email="kakar@gmail.com")
kakar_relation = Relation.objects.get(user=kakar)
t1 = kakar.relation.follows_tag.all()[0]
kakar_t1_relation = TagRelation.objects.get(user=kakar_relation, following_tag=t1)

As you can see, just to get the date I have to go through so much query. Is this the only way to get intermediate values, or this can be optimized? Also, I am not sure if this model design is the way to go, so if you have any recomendation or advice I would be very grateful. Thank you.

Show source
| django   | django-models   2017-01-02 06:01 1 Answers

Answers to Query intermediate through fields in django ( 1 )

  1. 2017-01-02 07:01

    You need to use Double underscore i.e. ( __ ) for ForeignKey lookup, Like this :

    user_tags = TagRelation.objects.filter(user__user__email="kakar@gmail.com").values("following_tag__name", "pub_date")

    If you need the name of the tag, you can use following_tag__name in the query and if you need id you can use following_tag__id.

    And for that you need to iterate through the result of above query set, like this:

    for items in user_tags:
        print items['following_tag__name']
        print items['pub_date']

    One more thing,The key word values will return a list of dictionaries and you can iterate it through above method and if you are using values_list in the place of values, it will return a list of tuples. Read further from here .

Leave a reply to - Query intermediate through fields in django

◀ Go back