I will demonstrate the workflow of creating a Django view via a simple line chart.
Inside the newly created bitcoin app folder, you should be able to find views.py, which stores all the views within the app. Let's edit it and create a view that outputs a Matplotlib line chart:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from io import BytesIO
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def test_view(request):
# Create a new Matplotlib figure
fig, ax = plt.subplots()
# Prepare a simple line chart
ax.plot([1, 2, 3, 4], [3, 6, 9, 12])
ax.set_title('Matplotlib Chart in Django')
plt.tight_layout()
# Create a bytes buffer for saving image
fig_buffer = BytesIO()
plt.savefig(fig_buffer, dpi=150)
# Save the figure as a HttpResponse
response = HttpResponse(content_type='image/png')
response.write(fig_buffer.getvalue())
fig_buffer.close()
return response
Since Tkinter is not available inside our server container, we need to switch the Matplotlib graphical backend from the default TkAgg to Agg by calling matplotlib.use('Agg') first.
The function test_view (request) expects a Django HttpRequest object (https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.HttpRequest) as input, and outputs a Django HttpResponse object (https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.HttpResponse).
To import a Matplotlib plot to the HttpResponse object, we need to save the plot to an intermediate BytesIO object first, which can be found in the io package (https://docs.python.org/3/library/io.html#binary-i-o). The BytesIO object acts as a buffer of the binary image file, such that plt.savefig can write a PNG file directly into it.
Next, we create a new HttpResponse() object with the content_type parameter set to image/png. The binary content inside the buffer is exported to the HttpResponse() object via response.write(fig_buffer.getvalue()). Finally, the buffer is closed to free up the temporary memory.
To direct users to this view, we need to create a new file called urls.py inside the {Project_folder}/crypto_stats/src/bitcoin folder.
from django.urls import path
from . import views
app_name = 'bitcoin'
urlpatterns = [
path('test/', views.test_view),
]
The line path('test/', views.test_view) states that all URLs with suffix test/ will be directed to the test_view.
We need to add our app's url patterns to the global patterns as well. Let's edit {Project_folder}/crypto_stats/src/crypto_stats/urls.py, and add the two lines commented as follows:
...
import profiles.urls
import accounts.urls
# Import your app's url patterns here
import bitcoin.urls
from . import views
...
urlpatterns = [
path('', views.HomePage.as_view(), name='home'),
path('about/', views.AboutPage.as_view(), name='about'),
path('users/', include(profiles.urls)),
path('admin/', admin.site.urls),
# Add your app's url patterns here
path('bitcoin/', include(bitcoin.urls)),
path('', include(accounts.urls)),
]
...
The line path('bitcoin/', include(bitcoin.urls)), states that every URL that begins with http://<your-domain>/bitcoin would be directed to the bitcoin app.
Wait for a few seconds until the development server reloads. You can now head to http://localhost:8000/bitcoin/test/ to see your plot.