2017-01-02 1 views
3

У меня есть простая модель отношений, где пользователь может следовать за тегом, как stackoverflow.Запрос промежуточных полей в django

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'] 

Теперь, чтобы получить результаты всех тегов пользователь имеет следующий вид:

kakar = CustomUser.objects.get(email="[email protected]") 
tags_following = kakar.relation.follows_tag.all() 

Это нормально.

Но для доступа к промежуточным полям мне нужно пройти через большой список других запросов. Предположим, я хочу, чтобы отобразить, когда пользователь начал после тега, я должен сделать что-то вроде этого:

kakar = CustomUser.objects.get(email="[email protected]") 
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 

Как вы можете видеть, только чтобы получить дату, я должен пройти через столько запроса. Это единственный способ получить промежуточные значения, или это можно оптимизировать? Кроме того, я не уверен, что этот дизайн модели - это путь, поэтому, если у вас есть какие-либо рекомендации или советы, я был бы очень благодарен. Спасибо.

ответ

1

Вы должны использовать двойное подчеркивание, т.е. (__) для ForeignKey поиска, Как это:

user_tags = TagRelation.objects.filter(user__user__email="[email protected]").values("following_tag__name", "pub_date") 

Если вам нужно имя тега, вы можете использовать following_tag__name в запросе, и если вы идентификатор потребности вы можете использовать следующий_tag__id.

И для этого вам нужно перебирать результат выше множества запросов, например:

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

еще одно, ключевое слово значения будет возвращать список словарей, и вы можете повторите это методом выше, и если вы используете values_list вместо значения, он вернет список кортежей. Read further from here.