Как выполнять задачи параллельно в Django (Асинхронное программирование)? - PullRequest
0 голосов
/ 01 августа 2020

Я разрабатываю простой view_count. Я просто хочу подсчитать просмотры, если запрашивающий пользователь не видел объект в течение дня со своей существующей учетной записью пользователя или IP-адресом. Я использую Django и djangorestframework.

Вот пример кода для действия извлечения.

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)

Это довольно просто. Я получаю запрашиваемый объект из базы данных и проверяю, просматривает ли объект пользователь или тот же IP-адрес в течение дня. Если объект сообщения не просматривается, мне просто нужно создать экземпляр PostView, что означает, что следующий просмотр не будет засчитан в день просмотра.

Мой вопрос: как я могу запустить его так, чтобы я вернул объект Response и одновременно запускать функцию, не дожидаясь ее завершения?

Заранее спасибо.

1 Ответ

1 голос
/ 01 августа 2020

Можно использовать сельдерей. Но, учитывая простоту вашей проблемы, я думаю, что проще использовать django -background-tasks. https://django-background-tasks.readthedocs.io/en/latest/.

Это очень просто:

  1. Добавление декоратора в вашу функцию
@background
def create_post_view
Вызов функции
create_post_view(....,schedule=timezone.now()) # at a specific time

Требуемая функция будет выполняться асинхронно.

...