At the end of this article I hope you will be able to understand the difference between a function based view and a class based view and also when to use them.
I'll be using a to-do list app to explain both terminologies this will be a part I of a three part series, in this part I’ll explain the difference between a Function based view and a class based view, while in part II we’ll be building the logic(views) of a to-do list app using a Function based views; in this part I'll explicitly guide you through the basics of a function based view and in the last episode part III same app, same functionalities but this time with a class based view approach
with that much said lets dive in.
PART I
Django views are where the logic of the application are been written and we have two main ways (function based view and class based view) of doing this which we will be covering in this article.
A function based view as the name implies is a view generated by Django's built-in functions, using a function based view shows the working parts of every method in your Django application, it shows how every aspects of your code works, if you're starting out as a beginner with Django I'll strongly recommend you start off with function based views as you'll see and understand the logic happening under the hood, although it requires more lines of codes but it makes it easy to comprehend what's going on and exactly what each line of code represents.
One very distinctive feature between a class based view and a function based view is the handling of HTTP responses, in function based view there is heavy use of conditioned logical statements as all requests are written in one function but with class based views we can separate these requests into various functions all still inside a class.
keep in mind that class based views does not replace function based views, both views are unique in their ways for solving specific problems as not all algorithm require a class based views approach and vice versa, choosing either is very dependent on what you’re building and how you intend to build it.
Bare in mind that all functions, both class based view and function based view must be:
- Callable
- Accept a HTTP request
- Return a HTTP request
Before we begin to build our to-do list app as a prerequisite for getting the best out of this article, you must have a working understanding of Django and how to set up a project in Django, how to start a Django application, how Django models work and also a basic understanding of Django views, templates and URL routing.
PART II
Kanyi is a very simple easy to use to-do list app with the CRUD functionalities, user login/logout, registration, user authentication and authorization and a search functionalities.
Kanyi was built using basic HTML, CSS and Django, using a function based view model, I'll explain some of these terminologies.
I expect you must have already had your project running and your costumed app installed.
DJANGO MODELS
Create a django model called Task
in models.py
Line 6; We define a model named Task
Line 7-11; are the various fields our frontend user will be interacting with
Line 7; establishes a one to many relation with our Task model using the ForeignKey model; Django comes with so many built in functions, class and attributes, a default User model is already created for us, to be able to use it we need to import it first in Line 2.
Explanation of a one-to-many relationship
One user having multiple tasks is an example of a one-to-many relationship
on_delete = models.CASCADE
Instructs the database to delete all task created by a User, if the user is deleted
Line 8; title is a charfield which by default must have a specified max_length
null=True
means that an empty field can exist in the database
blank=True
means a blank field can be submitted
Line 10; takes in a Boolean and its default value is set to false
Line 11; create a time stamp each time a task is created, it is automated with auto_add_now = True
attribute
Class Meta
describes the behaviour of your model field, like how the data are been rendered.
Intentionally skipped the basics of how to set up a Django project and app so we can focus on the purpose of this article
DJANGO VIEWS
now we move to views.py
where we create our function based views, the views.py
deals with the logic of your Django application
We create a view function for each of our CRUD functionality i.e a function view to Create, Read, Update, Delete (CRUD) tasks.
We start with the read function called tasklist
@login_required
is a Django decorator that limits only authenticated(logged in) users access to this function of the application, typically we add it to nearly all functions here
What is a decorator?
A decorator restrict access to views based on authentication
Difference between decorator and mixin
A decorator add a new function to an object without changing other object instances of the same class.
A mixin inherits from multiple parent classes.
Every Django function must take in a request (POST or GET) and also return a request.
In Line 110; we want to get all the objects(tasks) from our model Task, we filter the Task model by the user who created the tasks.
In Line 111; now we’ve gotten the Users
tasks we want to filter
it further by how many tasks has been completed
by this user
and count them
In Line 112; a search functionality is included; we get the inputted search word with request.GET.get(‘search_input’)
Two basic functions can be performed in our tasklist function
- The user can perform a search in the search form
- The user can view all their tasks.
So, if the User performs a search we want to filter the search this time from the Task model by the authenticated user and the title of the task title__icontains=search_input
else just display all the users tasks
We make use of the context dictionary for objects we intend to use with our template engine.
Like I stated earlier every Django function takes in a request and returns one.
taskdetail view function
Take's in a request(POST)
and a PrimaryKey( a unique identifier)
By default for each task created a unique ID is also created, we access that ID using the PrimaryKey; by default for each model created in Django, Django also creates a unique id, so every of our item created has a unique id, we use the pk variable to access the unique id’s, so in a nutshell the first line takes in a request(get) and a unique id(pk)
the rest lines of codes are bunch of repeated codes already explained above.
taskedit view function
To build an update/edit function using Django’s function based views, we make use of Django’s pre built ModelForm(not mandatory) it is a matter of choice.
DJANGO FORM
Django's ModelForm is used to directly convert a model into a Django form
TaskEdit
inherits all the cool stuffs Django's ModelForm
gives us model = Task
the model we’ll be working with, with this form
fields = [‘title’, ‘description’, ‘completed’]
the specific fields to be displayed in our form in the frontend or as an alternative we can choose to show all fields with fields = ‘__all__’
Import the TaskEdit
form into your views.py
form = TaskEdit()
without the instance = task
attribute will return a blank form, which we do not want, we want it refilled with what was there initially, hence form = TaskEdit(instance = task)
If the request method is post, we want to pass in the users request and the instance of the task
If the form is valid, save and redirect the user back to the home page indicating the task has been successfully updated
Question: what constitutes a valid form in Django?
Django provides built-in checks to validate data in a form, one of those checks is if it contains a CSRF token in a request.POST
method. the is_valid()
function is used to perform a clean and easy validation on each data.
Django’s delete view function is quite self explanatory, get the specific task to delete via its unique identifier(PrimaryKey)
use the Django’s delete()
function to delete the task
To build a create view function, this time we do not make use of Django's prebuilt ModelForm
but we create ours using basic HTML
I just want the reader of this article to be exposed to the various options we have when building cool stuffs with Django.
We pass in the title
and description
of the task which has already been created with HTML in our front end.
Call the .create()
function which creates an object in Django, this takes in an attribute of the authenticated user, title of the task and the description, task is saved and user is redirected to the home page to indicate a successful task has been created.
AUTHENTICATION and AUTHORIZATION
Before we build our login/logout and registration functionality, a little intro into the difference between Django's authentication and authorization.
Django’s authentication system handles both authentication and authorization.
Authentication verifies the claims of a user, authorization determines what an authenticated user can do.
I needed to explain this, some Django dev authenticate a user using auth.authenticate()
others just use .authenticate()
Login view function
Our registration and login share the same template login-register.html
using Django’s template engine if the page is set to login we display the login form else a signup form
Once a user has already been authenticated(logged in) we want to make it impossible for them to access the login page again
get the username and password from our front end HTML form, clean the data by adding .lower()
function, in other to make our login function not case sensitive.
Authenticate this user to a variable name user
if the user exists we make use of Django's login()
function, which takes in request and the user.
Else, display an error message if the user does not exist
This view usually doesn’t come with a template to render, it’s very straight forward as it makes us of Django's .logout()
function
We just include it in our urls.py
Lastly, we build our registration function using Django's UserCreationForm
No need for modification as we did to our ModelForm
we need all the functionalities of this form.
Pass in the request post, if the form is valid, we commit a false save to clean our data again, to ensure it’s not case sensitive, save the user after, else if the form isn’t valid display an error
Note:
We can perform an else statement that takes care of invalid passwords i.e if the passwords aren’t the same or an else statement that handles error messages for invalid email address, but for the purpose of this tutorial lets just stick to one error message for all errors an unauthenticated user may encounter.
Django's OS function
Django has a special function called the OS module, this module provides function for creating or deleting a directory, fetching its contents, changing and identifying the current directory
Below is the GitHub repo to the full project.
GitHub repo
Below is the link to where this project is been deployed.
Kanyi
Top comments (1)
Great article!