BUILDING A SIMPLE APP WITH DJANGO’S FUNCTION BASED VIEWS
Tags: webdev, django, python, tutorial
Published: 2022-07-19 14:13:53

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`

![Django models](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmoffoouun0vx7v3mv2n.png)
**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**


![tasklist view function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d253jz5lfj0yqkm1ab8.png)

`@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
1. The user can perform a search in the search form
2. 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**

![An image of task detail  view function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y68i67g7rgi04d7fioer.png)

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**

![An image of task detail  view function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1v5b3hn8q3nbvmiuwljf.png)

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

**forms.py**
![An image of ModelForm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gosg90n950l7vq8c0tqb.png)

`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.

**Delete view function**
![An image description of the delete view function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eeztj8y6ti31ivvjykd2.png)

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

**Create view function**
![An image description for a view function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxtcjm1l6q98v7j8y4x1.png)

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**

![Image description of a Login view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skc8fwsw1495800o3on3.png)

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

**Logout view function**
![Image description for logout view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jle1hdi2xen3jiysylqc.png)

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`
![Image description for registration view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6tm9jl3ps1yzo3zvlxs.png)

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](https://github.com/TimOsahenru/Kanyi_app.git)

Below is the link to where this project is been deployed.
[Kanyi](https://kanyi-app.herokuapp.com/)