Question: Query intermediate through fields in django

Question

Query intermediate through fields in django

Answers 1
Added at 2017-01-02 06:01
Tags
Question

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)
kakar_t1_relation.pub_date

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.

Answers
nr: #1 dodano: 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 .

Source Show
◀ Wstecz