Shroomcast is an app that I intented to use to learn Django Class-based views, as I indicated in my first article, which I published on LinkedIn only.
What are Class-based views, though?
View types in Django
Django allows to create views in two ways:
- Original Function-based views
- More advanced Class-based views
Function-based views
Function-based view is a type of view present in Django since it’s conception. It’s fairly simple, especially with Python’s easy to understand syntax. Function-based views will be the first views you create if you wish to learn Django.
They mainly consist of function definition, followed by its body, where you can manipulate the data before rendering the outcomes in the template. You typically return a template and some data (known as context in Django) from a function-based view, but you may also send back an http response object.
Here's probably the simplest example of function-based view:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hey, I won’t display weather, but I can pass a message!")
And here’s a bit more complicated one:
def index(request):
context = {“msg”: “I could display weather, but this guy wanted to use CBVs, so I won’t. At least not in this app…”}
return render(request, “index.html”, context)
Both of these views will display a message (but the second one on top of being more complex, will need some more stuff to work properly than the first one). The first approach to a function-based view allows to display a message only. The second one, however, allows for many data transformations before returning anything.
Class-based views
Class-based views allow you to quickly create basic web-views such as a plain index page, or a page with a form, or a paginated list.
They are more challenging to implement than function-based views and fall short if it comes to building more complex views, like for example ones that call several endpoints simultaneously and then parse the data received. If you want to create such a complicated view, you should switch back to function-based views.
The function-based view realizing several complex tasks will be hellishly long, but unlike class-based view it won’t employ predefined, abstract methods and attributes. Sometime creating a view that realizes several complex tasks as a CBV might be even almost impossible (been there, tried that).
If you want to learn more about Class-based views, here are two great sources:
- https://docs.djangoproject.com/en/4.2/topics/class-based-views/
- https://www.youtube.com/watch?v=GxA2I-n8NR8&list=PLOLrQ9Pn6caxNb9eFZJ6LfY29nZkKmmXT
Shroomcast’s structure
Shroomcast wasn't meant to be a complicated app, so CBVs were perfect for it. I needed the app to:
- Tell the weather
- Store Visual Crossing Key and utilize it when making API calls
- Let the user know how many query points they have used and how many are still available
- Since all this new information might be overwhelming for a new user, an informative About section was necessary
I chose a form view to display the weather since you can handle forms with it while not creating objects in your database. To accept the Visual Crossing key and then store it, I chose CreateView, which is similar to FormView but creates objects in a database. For the view that would inform the user about the query points they've used so far, I decided on the simple TemplateView. The same went for the "about" page which is a so-called "wall of text".
The user should be routed from the first page depending on whether they have previously provided the system with the Visual Crossing key or not, therefore I designed IndexView as a RedirectView.
A challenge right at the beginning of the project
Django views need templates to show anything to user, and after I have created a very first view, Django couldn’t “see” the template associated with this view. I went to the documentation, but there you have them asking you to make paths like this:
app_name/templates/app_name/template_name.html
From my point of view (as a person who've worked with words for more than 10 years), repeating the name in the route looks bad (yes, I prefer using clean code principles). So I searched for a way to make a simple folder structure for the templates, like:
app_core/templates/template_name.html
and somewhere else in the docs I have found that if one wants to put the templates in a custom directory, they should put the path to it in the DIRS list in the TEMPLATES constant in the settings.py file, like so:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
(…),
],
},
},
]
And so I have found a way to have the templates on the path that I wanted, but I still wonder, if there isn't a more elegant method. If any Django experts happen to read this article, please share how you would approach this problem.
I also wonder, whether the clean code approach wasn't my enemy in this case, and whether I shouldn't have stayed with the default way that documentation suggests 🤔
Summary
Shroomcast uses more elaborate but faster to implement Django class-based Views. Five views of the following types - TemplateView, RedirectView, FormView and CreateView - comprise the project features.
If you’d like me to delve deeper into any of the topics I brought up in this article, please let me know and see you in the next article in a while 😊
Top comments (0)