More Efficient List Views with Pagination:
We will apply pagination in views
- use paginator for tweet_feed_view in /tweets/api/views.py ```python from rest_framework.pagination import PageNumberPagination # new
@api_view([‘GET’]) @permission_classes([IsAuthenticated]) def tweet_feed_view(request, args, *kwargs): paginator = PageNumberPagination() # new paginator.page_size = 20 # new
user = request.userqs = Tweet.objects.feed(user)paginated_qs = paginator.paginate_queryset(qs, request) # new# serializer = TweetSerializer(qs, many=True)serializer = TweetSerializer(paginated_qs, many=True)# return Response(serializer.data, status=200)return paginator.get_paginated_response(serializer.data)
after this setup, each page of [http://localhost/api/tweets/feed/](http://localhost/api/tweets/feed/) will only show a query set of 20 tweets, but also provides a link to its next and previous page.to test, runserver, access [http://localhost/api/tweets/feed/?page=2](http://localhost/api/tweets/feed/?page=2)<br /><br />Here we only can see 20 tweets, and 2 urls called "next" and "previous".<br />We are on page 2, so we have a "next" to page 3, and "previous" to page 1 (or homepage because there is no "?page="), and those are also pages with 20 tweets.- we better split feed view and pagination into tweet_feed_view and get_paginated_queryset_response in /tweets/api/views.py```python'''@api_view(['GET'])@permission_classes([IsAuthenticated])def tweet_feed_view(request, *args, **kwargs):paginator = PageNumberPagination()paginator.page_size = 20user = request.userqs = Tweet.objects.feed(user)paginated_qs = paginator.paginate_queryset(qs, request)serializer = TweetSerializer(paginated_qs, many=True)return paginator.get_paginated_response(serializer.data)'''def get_paginated_queryset_response(qs, request):paginator = PageNumberPagination()paginator.page_size = 20paginated_qs = paginator.paginate_queryset(qs, request)serializer = TweetSerializer(paginated_qs, many=True)return paginator.get_paginated_response(serializer.data)@api_view(['GET'])@permission_classes([IsAuthenticated])def tweet_feed_view(request, *args, **kwargs):user = request.userqs = Tweet.objects.feed(user)return get_paginated_queryset_response(qs, request)
nothing changes in actually shown feed view.
User Profile Serializer:
timestamp and user id:
we add a user variable for all tweets in /tweets/serializers.py
# ...class TweetSerializer(serializers.ModelSerializer):user = serializers.SerializerMethodField(read_only=True) # newlikes = serializers.SerializerMethodField(read_only=True)parent = TweetCreateSerializer(read_only=True)class Meta:model = Tweet# fields = ['id', 'content', 'likes', 'is_retweet']fields = ['user', 'id', 'content', 'likes', 'is_retweet', 'parent'] # newdef get_likes(self, obj):return obj.likes.count()def get_user(self, obj): # newreturn obj.user.id
runserver, and access http://localhost/api/tweets/

we can see the user id of the sender of each tweet is shown.further in /tweets/serializers.py
- also setup user in TweetCreateSerializer
both add “timestamp” ```python class TweetCreateSerializer(serializers.ModelSerializer): user = serializers.SerializerMethodField(read_only=True) # new likes = serializers.SerializerMethodField(read_only=True)
class Meta: model = Tweet
fields = [‘id’, ‘content’, ‘likes’]
fields = [
'user','id','content','likes','timestamp'
]
def get_likes(self, obj): return obj.likes.count()
def validate_content(self, value): if len(value) > MAX_TWEET_LENGTH:
raise serializers.ValidationError("This tweet is too long")
return value
def get_user(self, obj): # new return obj.user.id
class TweetSerializer(serializers.ModelSerializer): user = serializers.SerializerMethodField(read_only=True) likes = serializers.SerializerMethodField(read_only=True) parent = TweetCreateSerializer(read_only=True)
class Meta:model = Tweet# fields = ['user', 'id', 'content', 'likes', 'is_retweet', 'parent']fields = ['user','id','content','likes','is_retweet','parent','timestamp']def get_likes(self, obj):return obj.likes.count()def get_user(self, obj):return obj.user.id
<a name="XJoDg"></a>#### create user profile serializer and show that in tweets list:- create /profiles/serializers.py```pythonfrom rest_framework import serializersfrom .models import Profileclass PublicProfileSerializer(serializers.ModelSerializer):first_name = serializers.SerializerMethodField(read_only=True)last_name = serializers.SerializerMethodField(read_only=True)username = serializers.SerializerMethodField(read_only=True)follower_count = serializers.SerializerMethodField(read_only=True)following_count = serializers.SerializerMethodField(read_only=True)class Meta:model = Profilefields = ["first_name","last_name","id","bio","location","follower_count","following_count","username",]def get_first_name(self, obj):return obj.user.first_namedef get_last_name(self, obj):return obj.user.last_namedef get_username(self, obj):return obj.user.usernamedef get_following_count(self, obj):return obj.user.following.count()def get_follower_count(self, obj):return obj.followers.count()
- apply PublicProfileSerializer in /tweets/serializers.py
```python
…
from profiles.serializers import PublicProfileSerializer # new
…
class TweetCreateSerializer(serializers.ModelSerializer):
# user = serializers.SerializerMethodField(read_only=True)user = PublicProfileSerializer(source='user.profile', read_only=True)likes = serializers.SerializerMethodField(read_only=True)class Meta:model = Tweet# fields = ['id', 'content', 'likes']fields = ['user','id','content','likes','timestamp']def get_likes(self, obj):return obj.likes.count()def validate_content(self, value):if len(value) > MAX_TWEET_LENGTH:raise serializers.ValidationError("This tweet is too long")return value#def get_user(self, obj):# return obj.user.id
class TweetSerializer(serializers.ModelSerializer):
# user = serializers.SerializerMethodField(read_only=True)likes = serializers.SerializerMethodField(read_only=True)user = PublicProfileSerializer(source='user.profile', read_only=True)parent = TweetCreateSerializer(read_only=True)class Meta:model = Tweet# fields = ['user', 'id', 'content', 'likes', 'is_retweet', 'parent']fields = ['user','id','content','likes','is_retweet','parent','timestamp']def get_likes(self, obj):return obj.likes.count()# def get_user(self, obj):# return obj.user.id
```
runserver and access http://localhost/api/tweets/
At present, “user” is modified from id to a long serializer, while we can see first_name, last_name, etc.
