pythondjangofirebasehacker-news-api

python calling django's render function in an async callback not working


To better understand the language I started working on building out a client that consumes the Hacker News api. The below code is supposed to pull in the first 10 items from their jobs feed. It first gathers a list of the id's, iterates through those ID's, and makes an async request to get the item details, which fires the callback function when done. All of that is working fine. It appears however that the render function isn't returning anything when nested like this. When I hit this route, I get the following error message: The view feed.views.index didn't return an HttpResponse object. It returned None instead.

If I was coding this with Node, it would work fine so I am assuming that this is just a matter of me not understanding how the language (or possibly framework) does things with async requests and/or scoping. What am I doing wrong?

 def index(request):
    job_ids = firebase.get('jobstories', None)
    stories = []

    def append_story(story):
        stories.append(story)
        print(len(stories))
        if len(stories) == 10:
            return render(request, 'feed/index.html', {'items': stories})

    count = 0
    for ts_id in job_ids:
        if count < 10:
            count += 1
            firebase.get_async('item/' + str(ts_id), None, callback=append_story)

Solution

  • First of all you probably don't want to define append_story within the index function.

    Secondly, the reason you are failing is because every Django view must return a HttpResponse with something like return HttpResponse("Hello"). Since python/django doesn't support async out of the box, if you want to do async, consider using ajax instead. Here's an example of how you might do something like that: Django - How to use asynchronous task queue with celery and redis.

    Basically the idea is to just generate a view then use javascript to call an ajax view that pulls your firebase info and then update your page appropriately after getting the result.