def list(self, request, *args, **kwargs): """ 重载 list 方法,不列出所有 tweets,必须要求指定 user_id 作为筛选条件 """ user_id = request.query_params['user_id'] cached_tweets = TweetService.get_cached_tweet(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: # 这句查询会被翻译为 # select * from twitter_tweets # where user_id = xxx # order by created_at desc # 这句 SQL 查询会用到 user 和 created_at 的联合索引 # 单纯的 user 索引是不够的 queryset = Tweet.objects.filter( user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) # 一般来说 json 格式的 response 默认都要用 hash 的格式 # 而不能用 list 的格式(约定俗成) return self.get_paginated_response(serializer.data)
def test_create_new_tweet_before_get_cached_tweets(self): tweet1 = self.create_tweet(self.linghu, 'tweet1') RedisClient.clear() conn = RedisClient.get_connection() key = USER_TWEETS_PATTERN.format(user_id=self.linghu.id) self.assertEqual(conn.exists(key), False) tweet2 = self.create_tweet(self.linghu, 'tweet2') self.assertEqual(conn.exists(key), True) tweets = TweetService.get_cached_tweet(self.linghu.id) self.assertEqual([t.id for t in tweets], [tweet2.id, tweet1.id])
def test_get_user_tweets(self): tweet_ids = [] for i in range(3): tweet = self.create_tweet(self.linghu, 'tweet {}'.format(i)) tweet_ids.append(tweet.id) tweet_ids = tweet_ids[::-1] RedisClient.clear() conn = RedisClient.get_connection() # cache miss tweets = TweetService.get_cached_tweet(self.linghu.id) self.assertEqual([t.id for t in tweets], tweet_ids) # cache hit tweets = TweetService.get_cached_tweet(self.linghu.id) self.assertEqual([t.id for t in tweets], tweet_ids) # cache updated new_tweet = self.create_tweet(self.linghu, 'new tweet') tweets = TweetService.get_cached_tweet(self.linghu.id) tweet_ids.insert(0, new_tweet.id) self.assertEqual([t.id for t in tweets], tweet_ids)