Reputation: 811
I am developing a simple view_count. I just want to count the views if the requesting user has not seen the object for a day with its existing user account or ip address. I am using Django and djangorestframework.
Here is some sample code for retrieve action.
def get_ip_address(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def create_post_view(post, user, request):
print("before sleeping")
PostView.objects.create(post=post,
user=user,
ip_address=get_ip_address(request)
)
post.view_count += 1
post.save(update_fields=("view_count", ))
print(post)
class PostModelViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAdminOrReadOnly, ]
pagination_class = DefaultLimitOffsetPagination
def retrieve(self, request, *args, **kwargs):
obj = self.get_object()
user = request.user if request.user.id else None
vwd = PostView.objects.filter(post=obj.id,
user=user,
ip_address=get_ip_address(request),
viewed_on__startswith=date.today())
if not vwd:
create_post_view(obj, user, request)
obj.view_count += 1
return Response(PostDetailSerializer(obj).data,
status=status.HTTP_200_OK)
It is pretty simple. I get the requesting object from database and check if the object is viewed by the the user or the same ip address in a day. If the post object is not viewed I simple need to create PostView instance which means that next view is not going to be counted on viewed day.
My question: How can I run it in a way that I will return the Response object and at the same time fire the function and not wait it to complete?
Thanks in advance
Upvotes: 0
Views: 2244
Reputation: 1392
You can use celery. But, given the simplicity of your problem, I think it's easier to use django-background-tasks. https://django-background-tasks.readthedocs.io/en/latest/.
It's as easy as this:
pip install django-background-tasks
from background_task import background
@background
def create_post_view
from django.utils import timezone
create_post_view(....,schedule=timezone.now()) # at a specific time
The desired function will be executed asynchronosly.
Upvotes: 2