简体   繁体   中英

Getting all the tags associated with the parent object using django-taggit

I have models Restaurant & Review . Review has TaggableManager() I have no problem in making tags work for Reviews. But I also want to know all the tags that are associated with the Restaurant object.

I can write my own function that iterates through all reviews of the restaurant to get all the tags associated with the Restaurant. But I am looking for cleaner and easy way to get the tags that accomplishes it in a single DB query.

I don't think its possible in a single query but this solution will take five database queries:

# 1 query: Get restaurant
restaurant = Restaurant.objects.get(pk=pk)

# 2 query: Get content type of restaurant model
restaurant_ct = ContentType.objects.get_for_model(restaurant)

# 3 query: Get all reviews ids for a restaurant
reviews_ids = Review.objects.filter(content_type__id=restaurant_ct.id, object_id=restaurant.id).values_list('id', flat=True)

# 4 query: Get content type of review model
review_ct = ContentType.objects.get(app_label='review', model='review')

# 5 query: Get all tags
tags = TaggedItem.objects.filter(object_id__in=reviews_ids, content_type__id=review_ct.id)

But do note that the __in lookup on review ids might become costly on TaggedItem . But you wanted minimum database queries.

You can reduce one more query by fetching both content types of restaurant and review model in a single query but its not an elegant way:

ctypes = ContentType.objects.filter(
    app_label__in=['review', 'restaurant'],
    model__in=['review', 'restaurant']
)
assert len(ctypes) is 2
if ctypes[0].model == 'restaurant':
    restaurant_ct = ctypes[0]
    review_ct = ctypes[1]
else:
    review_ct = ctypes[0]
    restaurant_ct = ctypes[1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM