User Feed Including Following:

tweet_feed_view:

  • create tweet_feed_view in /tweets/api/views.py ```python

@api_view([‘GET’]) # http method the client === GET @permission_classes([IsAuthenticated]) def tweet_feed_view(request, args, *kwargs): user = request.user profiles = user.following.all() # user.following.all() -> All user profiles this user follow followed_users_id = [] if profiles.exists(): followed_users_id = [x.user.id for x in profiles] followed_users_id.append(user.id) qs = Tweet.objects.filter(useridin=followed_users_id).order_by(“-timestamp”) serializer = TweetSerializer(qs, many=True) return Response(serializer.data, status=200)

  1. - import tweet_feed_view in /tweets/api/urls.py
  2. ```python
  3. from django.contrib import admin
  4. from django.urls import path
  5. from .views import (
  6. tweet_detail_view,
  7. tweet_list_view,
  8. tweet_create_view,
  9. tweet_delete_view,
  10. tweet_action_view,
  11. tweet_feed_view, # new
  12. )
  13. urlpatterns = [
  14. path('', tweet_list_view),
  15. path('feed/', tweet_list_view), # new
  16. path('action/', tweet_action_view),
  17. path('create/', tweet_create_view),
  18. path('<int:tweet_id>/', tweet_detail_view),
  19. path('<int:tweet_id>/delete/', tweet_delete_view),
  20. ]

to test, runserver and access http://localhost/api/tweets/feed/
image.png
there is no actually following relationship found, and we need a more efficient way to call profiles in the database.

More Efficient Backend Lookups and Custom Model Managers:

  • we apply Q with 2 new functions in /tweets/models.py
  • Q stands for “query” ```python

from django.db.models import Q

class TweetQuerySet(models.QuerySet): def by_username(self, username): return self.filter(userusernameiexact=username)

  1. def feed(self, user):
  2. profiles_exist = user.following.exists()
  3. followed_users_id = []
  4. if profiles_exist:
  5. followed_users_id = user.following.values_list(
  6. "user__id", flat=True) # [x.user.id for x in profiles]
  7. return self.filter(
  8. Q(user__id__in=followed_users_id) |
  9. Q(user=user)
  10. ).distinct().order_by("-timestamp")
  11. # use query to pass user id and user
  12. # distint for the same element only appears once
  13. # order by reversed time

class TweetManager(models.Manager): def get_queryset(self, args, *kwargs): return TweetQuerySet(self.model, using=self._db)

  1. def feed(self, user):
  2. return self.get_queryset().feed(user)

  1. - and use those new models and model methods in /tweets/api/views.py
  2. ```python
  3. @api_view(['GET'])
  4. @permission_classes([IsAuthenticated])
  5. def tweet_feed_view(request, *args, **kwargs):
  6. user = request.user
  7. # profiles = user.following.all() # user.following.all() -> All user profiles this user follow
  8. # if profiles.exists():
  9. # followed_users_id = [x.user.id for x in profiles]
  10. # followed_users_id.append(user.id)
  11. # qs = Tweet.objects.filter(user__id__in=followed_users_id).order_by("-timestamp")
  12. qs = Tweet.objects.feed(user)
  13. serializer = TweetSerializer(qs, many=True)
  14. return Response(serializer.data, status=200)
  15. @api_view(['GET'])
  16. def tweet_list_view(request, *args, **kwargs):
  17. qs = Tweet.objects.all()
  18. username = request.GET.get('username')
  19. if username != None:
  20. # qs = qs.filter(user__username__iexact=username)
  21. qs = qs.by_username(username) # moved this part to a method in TweetQuerySet()
  22. serializer = TweetSerializer(qs, many=True)
  23. # return Response(serializer.data)
  24. return Response( serializer.data,status=200)