I am creating an application in which users can post tags related to it:
class Tag(models.Model): name = models.CharField(max_length=255, unique=True) class Post(models.Model): user = models.ForeignKey(User) body = models.TextField() tags = models.ManyToManyField(Tag) pub_date = models.DateTimeField(default=timezone.now) activity = GenericRelation(Activity, related_query_name="posts") class Photo(models.Model): user = models.ForeignKey(User) file = models.ImageField() tags = models.ManyToManyField(Tag) pub_date = models.DateTimeField(default=timezone.now) activity = GenericRelation(Activity, related_query_name="photos") class Activity(models.Model): actor = models.ForeignKey(User) verb = models.PositiveIntegerField(choices=VERB_TYPE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') pub_date = models.DateTimeField(default=timezone.now)
What I want to do is to get / filter a maximum of 5 last / last Activity objects, a list of users and a list of tags from the list of Post objects tag fields and return json using django-rest-framework for viewing on the client side.
For example, actions:
- UserA created a new Post obect with tags (#class, #school)
- UserB created a new Post object with tags (#professor, #teacher)
- UserC created a new Post object with tags (#school, #university)
- UserD created a new Post object with tags (#university, #school)
So, say I want to filter Activity with user_list=[UserA, UserC] and tag_list = [#class, #teacher]
He must return:
- UserA created a new Post obect with tags (#class, #school)
- UserC created a new Post object with tags (#school, #university)
- UserB created a new Post object with tags (#professor, #teacher)
To filter activity with users, I can request this method:
Activity.objects.filter(actor__in=user_list)
But how do I filter an Activity with a content_object (i.eost or Photo) field (i.e. Post.tags or Photo.tags)? Now I do this:
Activity.objects.filter(posts__tags__in=tag_l) Activity.objects.filter(photos__tags__in=tags)
So, to summarize, if I need actions with a list of users and a list of tags, I have to do like this:
activites = Activity.objects.filter( Q(actor__in=user_list) | Qposts__tags__in=tag_list) | Q(photos__tags__in=tag_list) )
But suppose there are more than two classes of the ContentType model, then I will have to add another Q(moreModel__tags__in=tag_list) . Therefore, I hope that there is a better way to optimize the process.
django django-models django-queryset django-rest-framework
Robin
source share