4

In this template i'm retrieving the price of Bitcoin from an API. At the actual moment, the price will be updated only when the page is refreshed, while i would like it to be updated without refreshing the whole page, dynamically.

This is my view:

def home(request):

    symbol = "BTCUSDT"
    tst = client.get_ticker(symbol=symbol)

    test = tst['lastPrice']

    context={"test":test}

    return render(request,
                  "main/home.html", context
                  )

And the template's line looks something like this:

<h3> var: {{test}} </h3> 

There are two problems here:

1) From the little i know, Django itself is not asynchronous, so i need to find a way to update that part of the template in real time, without having to refresh the whole page.

2) At the actual moment, the API is requested when the page is opened/refreshed, but to stream the price, it should be always running. I tried this (awful) solution: add a while true in the view, but of course it broke my code, executing only the part the while statement.

Any advice is appreciated :)

Jack022
  • 867
  • 6
  • 30
  • 91
  • In that case, you should make some JavaScript that calls the API and fetches the new price. For example with angular. Django is a *backend*, not a *front end*. – Willem Van Onsem Jun 28 '19 at 10:54
  • Either you want AJAX via jQuery, with the work being done on the back-end, or try updating the value through JS alone. This is pretty broad – roganjosh Jun 28 '19 at 10:54
  • Yeah, but essentially, the problem is that i don't understand where to put the code that keeps querying the api. I mean, if i put it into the view, it won't work – Jack022 Jun 28 '19 at 10:57
  • Why would it not work in the view? It works fine now. The point is, your Ajax would repeatedly call the view and update the frontend as necessary. – Daniel Roseman Jun 28 '19 at 10:58
  • @DanielRoseman because at the actual moment, the api is retrieved only when i open the page, according to my code, while it should be retrieved every tot seconds – Jack022 Jun 28 '19 at 11:00
  • For periodic updation or realtime better use django-channels with websockets – Pavan Kumar T S Jun 28 '19 at 11:01
  • Yes. **That is exactly why everyone says you should use Ajax**. The Ajax code will call your view every few seconds. – Daniel Roseman Jun 28 '19 at 11:01
  • @DanielRoseman got it! But where would the Ajax part go? In the template? Sorry but i haven't used Ajax until now – Jack022 Jun 28 '19 at 11:03
  • Yes, it's JavaScript, separate from Django. You will need a view function that returns the specific data you want, but you need to call that view from the front-end. The page that the user lands on can have a function that keeps polling a view function (separate from the one that rendered the whole page) to get updated information. You then update a specific `div` (or otherwise) with Ajax. – roganjosh Jun 28 '19 at 11:04
  • Understood! I'm going to look into this, thanks! – Jack022 Jun 28 '19 at 11:10
  • 1
    Check out [Server Sent Events](https://stackoverflow.com/questions/54326515/how-can-i-make-sse-with-python-django) – Ivan Jun 28 '19 at 11:26
  • @DanielRoseman one more thing, i have been suggested to use Django Rest Framework, would it be a better solution than using Ajax? – Jack022 Jun 28 '19 at 13:11

1 Answers1

6

You should separate your frontend and backend in order to dynamically update the DOM contents without needing to render the whole DOM each time.

The responsibility of frontend would be to request and fetch the latest values when a user does an action that warrant a refresh or fetching of updated data. The request need to made asynchronously via e.g. AJAX. The newer JS frameworks e.g. React, Vue use virtual DOM that use an intermediate virtual DOM that they use to push the updates and finally update the real DOM in a single go; which makes them very performant.

The (Django) backend should expose an API that would take (AJAX) requests from backend for specific resources, and serve them.

A nice framework for Django is DRF (Django REST Framework), which exposes REST endpoints that you can call from frontend via AJAX and get reponse back so that the frontend can do necessary updates.

This is a failrly high level view, and is written to give you an idea that you can implement by digging deeper.

heemayl
  • 39,294
  • 7
  • 70
  • 76
  • One more thing @heemayl: you said, 'it needs to refresh when the user does something', but in this case, the user won't be doing anything. I mean, the page will just have to be updated in real time, without any inputs; just viewing the page. Is that the same? Should i still go with DRF? – Jack022 Jun 28 '19 at 13:08
  • @Jack022 Yes. What I meant is that it would be event based. And the event would be a frontend event e.g. user clicks something, a certain time passed, some external input and so on. Then the frontend would send AJAX request to backend to fetch new data and DRF will serve the data requested. As you can see DRF only serves what requested, the frontend needs to do the asking. – heemayl Jun 28 '19 at 13:11
  • Ok, but what i mean, is that in this case there should not be an input by the users. What i'm looking for is, the user opens the page and he will see a part of the page with the numbers updating in real time. Sorry, but i'm new to this stuff :) – Jack022 Jun 28 '19 at 13:15
  • @Jack022 Yes. You can do that. I would suggest you to start reading the basics of AJAX :) – heemayl Jun 28 '19 at 13:17
  • Thank you @heemayl. Really last last thing. What is the difference between using this solution or using Django-Channels to update the page, or something like SocketIO? – Jack022 Jun 28 '19 at 13:18
  • @Jack022 Django channels are used for `websocket` communication where the backend keeps a persistent connection with the frontend to push asynchronously. SO uses websockets FWIW. – heemayl Jun 28 '19 at 13:21
  • @Jack022 Glad, I could help :) – heemayl Jun 28 '19 at 14:41