1

Hello I encountered a problem which i am not able to solve by myself. I tried to call function create_with_celery inside create but it didnt work

How should I call create.delay with proper arguments? I don't know how to properly call create function to make workers create objects

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    @app.task(bind=True)
    def create(self, request):
        article = Article.objects.create(link=request.data['link'])
        article.save()
        serializer = ArticleSerializer(article, many=False)

        words = WordList(article.link)
        # take every 90nth word for faster loading only dev approach
        i = 0
        for word in range(0, len(words.list)):

            # try to take word from database
            i += 1
            try:
                existing_word = Word.objects.filter(name=words[word])
                Word.objects.create(
                    name=existing_word[0].name,
                    advance_level=existing_word[0].advance_level,
                    definition=existing_word[0].definition,
                    article=Article.objects.get(id=article.id)
                )
                print('word nr {}/{} "{}" created from database'.format(i,
                                                                        len(words.list), words[word]))

            except:
                # if it's not existing fetch data from web
                Word.objects.create(
                    name=words[word],
                    advance_level=get_word_frequency(words[word]),
                    definition=get_word_definition(words[word]),
                    article=Article.objects.get(id=article.id)
                )
                print('word nr {}/{} "{}" fetched from web'.format(i,
                                                                   len(words.list), words[word]))

        response = {'message': 'Article created ', 'result': serializer.data}
        return Response(response, status=status.HTTP_200_OK)

Im trying to do something like this but I get error "Object of type 'Article' is not JSON serializable"

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    @app.task(bind=True)
    def create_with_celery(self, article, serializer, words, req):
        i = 0
        for word in range(0, len(words.list)):
            # try to take word from database
            i += 1
            try:
                existing_word = Word.objects.filter(name=words[word])
                Word.objects.create(
                    name=existing_word[0].name,
                    advance_level=existing_word[0].advance_level,
                    definition=existing_word[0].definition,
                    article=Article.objects.get(id=article.id)
                )

                print('word nr {}/{} "{}" created from database'.format(i,
                                                                        len(words.list), words[word]))

            except:
                # if it's not existing fetch data from web
                Word.objects.create(
                    name=words[word],
                    advance_level=get_word_frequency(words[word]),
                    definition=get_word_definition(words[word]),
                    article=Article.objects.get(id=article.id)
                )
                print('word nr {}/{} "{}" fetched from web'.format(i,len(words.list), words[word]))


def create(self, request):
    article = Article.objects.create(link=request.data['link'])
    article.save()
    serializer = ArticleSerializer(article, many=False)
    words = WordList(article.link)
    req = request

    self.create_with_celery.delay(article, serializer, words, req)

    response = {'message': 'Article created ', 'result': serializer.data}
    return Response(response, status=status.HTTP_200_OK)
4
  • Hey I'm having similar issue. Did you solve it? @Adrian Zyskowski Commented Feb 14, 2021 at 2:31
  • @YashaswiniBhat As someone mentioned below you can only pass basic JSON to celery. You can't pass directly ModelViewSet's create function to celery with Python objects as arguments (self, request). Commented Feb 15, 2021 at 11:48
  • You should have your celery tasks in tasks.py file and these tasks should only receive basic types arguments (int, string, etc..) Commented Feb 15, 2021 at 11:51
  • I will try to answer you directly if you create another question on stack :) Commented Feb 15, 2021 at 12:07

2 Answers 2

1

You can only pass basic types supported in JSON.

Sign up to request clarification or add additional context in comments.

1 Comment

Do you maybe have an idea what would be a good implementation?
1

Take in mind that celery is a good tool to process async data, as I see what you try to do on ArticleViewSet, you could achieve that directly on the save method of the ArticleSerializer.

2 Comments

You mean I can write the functions create and create_with_celery in serializers.py on ArticleSerializer?
Yes that is the idea, use the Serializers as you use django Forms, in the views should not be all that heavy logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.