【发布时间】:2017-05-17 23:24:02
【问题描述】:
我创建了一个应用程序,用户可以在其中发布相关标签:
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)
我想要做的是获取/过滤最多 5 个最新/最近的 Activity 对象,其中包含用户列表,以及来自 Post 对象标签字段列表的标签列表,并使用 django-rest-framework 返回 json 以查看在客户端。
例如活动:
- UserA 创建了一个带有标签的新 Post 对象(#class, #school)
- UserB 创建了一个带有标签的新 Post 对象(#professor, #teacher)
- UserC 创建了一个带有标签的新 Post 对象(#school, #university)
- UserD 创建了一个带有标签的新 Post 对象(#university, #school)
假设我想用user_list=[UserA, UserC] 和tag_list = [#class, #teacher] 过滤活动
它应该返回:
- UserA 创建了一个带有标签的新 Post 对象(#class, #school)
- UserC 创建了一个带有标签的新 Post 对象(#school, #university)
- UserB 创建了一个带有标签的新 Post 对象(#professor, #teacher)
要过滤带有用户的Activity,我可以这样查询:
Activity.objects.filter(actor__in=user_list)
但是,如何使用 content_object 的(即 Post 或 Photo)字段(即 Post.tags 或 Photo.tags)过滤 Activity?现在我正在这样做:
Activity.objects.filter(posts__tags__in=tag_l)
Activity.objects.filter(photos__tags__in=tags)
总而言之,如果我需要包含用户列表和标签列表的活动,我必须这样做:
activites = Activity.objects.filter(
Q(actor__in=user_list) |
Qposts__tags__in=tag_list) |
Q(photos__tags__in=tag_list)
)
但假设会有两个以上的 ContentType 模型类,那么我必须再次添加另一个 Q(moreModel__tags__in=tag_list)。所以,我希望有更好的方法来优化这个过程。
【问题讨论】:
标签: django django-models django-rest-framework django-queryset