Django Custom Template Tags | Django Tutorial

Template tags are code snippets used to add functionality in templates. Django offers a variety of template tags such as {% if %}, {% for %}, {% block %}. Besides, Django allows us to create our own set of custom tags and make them available in the Django templates. We can extend the template engine by defining custom tags. Then it will be available to our templates. In this tutorial, we will discuss Django Custom Template Tags.

Why We Use Template Tags

Suppose, we have an eCommerce website to build. It will contain multiple category products and we will have to show all the categories in our ‘navbar’. To do this we will have to pass the queryset ‘Categories.objects.all()’ from each of our views to show in each template. But, Using template tags we can skip this redundancy. We will make a custom template tag that will show all the categories and load it into our ‘base.html’ file.

Custom Template Tags

Django provides the following helper functions that allow us to create our own template tags in an easy manner:

  • simple_tag: Processes the data and returns a string
  • inclusion_tag: Processes the data and returns a rendered template.

Simple Tag

It returns simple string.

Let’s start creating our first template tag. Firstly, we will create a directory named ‘templatetags’ & add __inti__.py file to ensure the directory is treated as a Python package. Then we will create another file named new_template_tags.py

directory structure

new_template_tags.py

from first_app.models import Person
from django import template

register = template.Library()

@register.simple_tag
def all_persons():
    return Person.objects.count()

@register.simple_tag
def male_persons():
    return Person.objects.filter(gender='M').count()

I created an instance ‘register’ of ‘template.Library()’ and used it as “@register.simple_tag” decorator. It will help us to register our template into the Django template library. This can be named anything but naming it ‘register’ is strongly recommended.

Now, this template tag can be used inside any template after loading it in the template using “{% load new_template_tags %}”.

Inside ‘persons.html’

{% load new_template_tags %}

<h2>All Persons {% all_persons %}</h2>
<h3>Male Persons {% male_persons %}</h3>

Output:

This is the power of template tags. We can process any data and use them in any template we want.

Inclusion Tag

Inclusion is the kind of template tag which displays some data by rendering a specific template. Now, we will change our ‘all_persons’ tag into an inclusion tag.

new_template_tags.py

@register.inclusion_tag('all_persons.html',takes_context = True )
def all_persons(context):
    # Fetch Data From Person Model
    persons = Person.objects.all()
    context = {
        'persons': persons,
    }
    return context

all_persons.html

{% for person in persons %}

{% if person.first_name == 'Zaira' %}
    <a href="{% url 'person-detail-view' person.id %}">   <h3>{{person.first_name}} {{person.last_name}}</h3></a>
    <h4>{{person.email}}</h4>
{% else %}
    <a href="{% url 'person-detail-view' person.id %}"> <h3>{{person.first_name}} {{person.last_name}}</h3></a>
    <h4>{{person.email}}</h4>
{% endif %}

{% endfor %}

We have retrieved the data rendered by our template tag inside all_persons.html template. Now, this ‘all_persons.html’ can be attached inside any other template.

persons.html

{% extends 'base.html' %}
{% block content %}
<h2>All Persons</h2>

{% all_persons %}

{% endblock %}

Output

We can also pass arguments in our template tags.

Django Custom Model Manager | Model Manager

Django Custom Model Manager

In this article we are going to discuss Django Custom Model Manager & Django Default Model Manager. So, What is a manager?

A Manager is a bridge through which database queries talk with Django models. In other words, it is actually an interface which interacts with application and database. There is at least one Manager that exists for every model in a Django application named objects. It is the default manager of every model that retrieves data from the database.

In this article we will discuss about creating Custom Model Managers & why should we use them.

Benefits of using Managers

Writing clean, efficient, maintainable code and following the DRY (Don’t Repeat Yourself) software architecture principle is industry demands. The django model managers keeps the querying in a centralized place in our django application. We can call those queries where we need them instead of writing them in each View. So, the benefits of using Django Managers are:             

  1. Clean code.
  2. Efficient code.
  3. Maintainable code.
  4. Writing common query code for the model which are reusable.
  5. Following DRY (Don’t Repeat Yourself) principle.

Firstly, we will create a model

class Person(models.Model):
      GENDER = (
        ('M', 'Male'),
        ('F', 'Female'),
    )

    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField(unique = True,null=True)
    gender = models.CharField(max_length=1, choices= GENDER,default='N/A')

    #will add our manager here


    class Meta:
        verbose_name_plural = 'All Persons'

    @property
    def full_name(self):
        return f'{self.first_name} {self.last_name}'

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

After running migrations let’s create some objects in the admin panel.

Objects of Django Model
Objects of Person model

Here, we have 6 person objects. The query operations will be like these…

>>> from first_app.models import Person
>>>
>>> Person.objects.all()
<QuerySet [<Person: Inayra Mutahharah>, <Person: Zaira Anaya>, <Person: Zahra Ibnat>, <Person: Jon Doe>, <Person: Yeasir Arafat>, <Person: Arafat Yeasir>]>
>>>
>>> Person.objects.filter(gender = 'F')
<QuerySet [<Person: Inayra Mutahharah>, <Person: Zaira Anaya>, <Person: Zahra Ibnat>]>
>>>
>>> Person.objects.filter(gender = 'M').count()
3

Here, ‘objects’ is the name of our default manager which is capable of doing all basic QuerySets, then why would we need a custom model manager? If need these queries in different views we will have to write these long lines of codes everywhere & if we want to change some thing we will have to change everywhere. This tough and monotonous task can be simplified using Django Mangers. Let’s create custom managers for doing these…

Custom Model Managers

We will inherit the properties of models.Manager.

class PersonManager(models.Manager):
    def male_persons(self):
        return self.filter(gender='M')
      
    def female_persons(self):
        return self.filter(gender='F')

    def total_persons(self):
        return self.all().count()

Now we will add this manger as our Person model’s manager. To do this we will have to add this line of code in our Person model.

#will add our manager here
objects = PersonManager()

We are ready to query with our manager.

>>> from first_app.models import Person
>>> males = Person.objects.male_persons()
>>> males
<QuerySet [<Person: Jon Doe>, <Person: Yeasir Arafat>, <Person: Arafat Yeasir>]>
>>> females = Person.objects.female_persons()
>>> females
<QuerySet [<Person: Inayra Mutahharah>, <Person: Zaira Anaya>, <Person: Zahra Ibnat>]>

We can change the default manger name with whatever we want. Let’s name it ‘persons’.

#will add our manager here
persons = PersonManager()
>>> from first_app.models import Person
>>> Person.persons.all()
<QuerySet [<Person: Inayra Mutahharah>, <Person: Zaira Anaya>, <Person: Zahra Ibnat>, <Person: Jon Doe>, <Person: Yeasir Arafat>, <Person: Arafat Yeasir>]>
>>>
>>> Person.persons.all().count()
6

Django Form and ModelForm | Django Tutorial

Forms are basically used for taking input from the user. For adding, updating, retrieving that information to databases using GET or POST request. There is two forms classes in Django which is used to create HTML forms. Form & ModelForm. The difference between the Form & ModelForm class is that ModelForm class needs a model to create a form, but the Form class does not require a Model. We will discuss both here. Each field of the Form class map to the HTML form  <input>  element and each field has custom validation logic. Django does three distinct parts of the work involved in forms:

  • Prepares and Restructures data to make it ready for rendering
  • Creates HTML forms for the data.
  • Receives and Processes submitted data from the user.

forms.Form

Creating forms in Django is similar to creating a model. We just need to inherit from Django Form class and the attributes of the class will be the form fields. 

Let’s see an example. We will make a ‘forms.py’ file and add this code snippet to it.

from django import forms  

class UserForm(forms.Form):
    first_name = forms.CharField(label="Enter first  name",max_length=100)  

    last_name  = forms.CharField(label="Enter last name", max_length = 100)  
views.py
from first_app.forms import UserForm  
      
def user_form(request):  
    form = UserForm()  
    return render(request,"user-form.html",{'form':form})  
user-form.html
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Index</title>  
</head>  
<body>  
  <form method="POST">  
       {% csrf_token %}  
       {{ form.as_p }}  
        <button type="submit" class="save btn btn-default">Save</button>  
   </form>  
</body>  
</html>  

Here, {% csrf_token %} token adds protection against Cross Site Request Forgeries. This is used only in POST requests. We don’t need it with GET requests.

Now, let’s add URL in urls.py

urlpatterns = [
         path('user-form', user_form, name='user-form'),
]

We created a UserForm that contains two fields of CharField type. CharField is used to create an HTML text input component in the form. The label sets the HTML label of the component and ‘max_length’  sets the length of an input value. Here, we didn’t put HTML <input> tags. But {{ form }} variable will create necessary HTML tags for us. When rendered, it will produce the following HTML code in the browser.

Run Server and access the form at browser by going to this url localhost:8000/user-form, and it will produce the following output.

We cannot generate the ‘submit’ button or <form> tag using Django, We’ll have to provide those in the template.

How to Render Django Forms

There are three in-built output options for django forms.

  • {{ form.as_table }} will give output as table cells wrapped in <tr> tags
  • {{ form.as_p }} will give output wrapped in <p> tags
  • {{ form.as_ul }} will give output wrapped in <li> tags

Some Form fields and their details are given in the below table.

Name Class HTML Input
BooleanField  BooleanField(**kwargs) CheckboxInput
CharField CharField(**kwargs) TextInput
ChoiceField ChoiceField(**kwargs) Select
DateField DateField(**kwargs) DateInput
DateTimeField DateTimeField(**kwargs) DateTimeInput
DecimalField DecimalField(**kwargs) NumberInput
EmailField EmailField(**kwargs) EmailInput
FileField FileField(**kwargs) ClearableFileInput
ImageField ImageField(**kwargs) ClearableFileInput

Let’s see a complete example. We will create an HTML form with the help of the Django Form class and saving them in a database.

Instantiating Form in Django

Now, we need to instantiate the form in views.py file. See, the below code.

from first_app.forms import UserForm
  
class AddPersonViewTwo(FormView):
    form_class = UserForm
    template_name = 'user-form.html'
    success_url = '/all-persons'

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # created a person object
        obj = Person()
        # clean data from 'form' and assign them into objects attributes
        obj.first_name = form.cleaned_data['first_name']
        obj.last_name = form.cleaned_data['last_name']
        #finally save the object in db
        obj.save()
        return HttpResponse("Object Saved")

Firstly, we created a view and assigned the value of Class attributes (form_class, template_name, success_url). Secondly, we overrode the form_valid method of ‘FormView’ class where we created an object of Person class. As, we know our person class has four attributes; out of them two are required (first_name, last_name). We are also taking these two inputs through our form. Now, we will assign the values taken by ‘Form’ to our Person object attributes. We are done to save data in db. Now we will Add URL for this view and go to the link.

Our Templates will be same as our ‘user-form.html’

Output

Now, if we click the button ‘Add Person’ the data will be saved in the database.

Let’s check our database.

How to use ModelForm in Django

The differences between Form and ModelForm is a form created by forms. ModelForm is a form that is automatically created based on a specific model. forms.Form  and  forms.ModelForm are more closely related. The Form class allows us to validate data. It hardly matters if it is a GET, or POST request.

ModelForm is a subclass of the Form class. A ModelForm  works  almost  exactly like a Form class, except that it reads the list of fields from the attribute you provide. Underneath it all, a ModelForm actually just creates a Form with fields that are relevant to the fields of the model you specify, so you don’t have to do it manually.

ModelForm
class AddPersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ('first_name','last_name','email','gender')
View
from .forms import AddPersonForm

class AddPersonView(CreateView):
    form_class = AddPersonForm
    template_name = 'user-form.html'

HTML will be same as before.

Output 

Redirected To Details
In admin panel

In conclusion, use a forms.Form when you have data that you want to validate and use forms.ModelForm when you want to validate data that you will store in your database, using a db.models.Modelclass.

Role-Based User Authorization in Graphene-Django

User authorization is a vital part of any business application. Every developer faces the authorization challenge. There are many ways to implement authorization in Django. Django has a built-in permission-based authorization system, and there are some third-party apps like django-guardian and django-rules.

In our previous article, we implemented Token-based authentication with
django-graphql-jwt
. It has also some useful decorators to implement authorization.

But in this article, I will share a custom way to implement role-based authorization in GraphQL. Maybe in the next article, I will share some other ways of authorizations with Django’s built-in permission module.

Let’s start writing some code.

Read More

User Authentication in Graphene-Django with JWT

In all most every project we need user authentication. Django has session-based built-in user authentication and authorization support. But in modern days most of our applications are stateless, so, we are covering here stateless user authentication with JWT.

If you are following our previous articles, you already created a blog app with Graphene-Django. We did not add user authentication for our blog app. Here we will use django-graphql-jwt with Graphene-Django.

Let’s do some basic setup.

Read More

Bulk Insert/Update/Delete in Graphene-Django

In GraphQL, we can do multiple inserts, update and delete at a time. The cool thing about GraphQL is we have a lot of control in our hands. In the GraphQL query, we can ask exactly what we need. As well as query, we can post as much data as we want with GraphQL mutation.

There are a lot of real-life scenarios where we need a bulk insert, update or delete. Specially, In our modern Single Page Applications (SPA), a user may create, update or delete multiple related items at a time. Though GraphQL makes it easy to send data for bulk upsert or delete, we need a fast, cleaner way to do it with Django. The main challenge here is, we have to do a faster, memory-efficient way to implement upsert with large batch size.

Read More

Server-Side Data Validation and Error Handling in GraphQL/Django

Introduction

Application security is an absolute necessity and it must be a top priority. To make our application secure, we must do server-side data validation. Because we can’t rely on client-side input validation. Certainly, client-side input validation can be manipulated in many ways, which will make our system vulnerable. Therefore, the same input validation must be performed on the server-side.

Any application can have errors. So, handling errors and returning back some informative messages to the end-user is very important. GraphQL does not send any status code with a response like REST. It sends an array called errors with the details of the error. The location and the path of the error are also included. So, handling errors in GraphQL looks pretty simple. But you may need custom error handling with server-side data validation. We will cover both types of error handling and server-side data validation in the following.

Read More

Unit Testing Graphene-Django API with Pytest – 3 Steps

In modern days, automated software testing is extremely important to kill the bugs during development. Unit testing is the first level of software testing, which a developer can not and should not avoid. Because it helps the developer to write bug-free, secure and robust codes.

What is Unit Testing?

Unit testing is a software testing method where every individual component and every single unit of the software is tested. Most of the time, unit testing is performed by the developer. Some times it is done by a QA engineer.

When you are doing TDD (Test Driven Development), you will write the unit test before starting the actual code. You can also write unit tests after finishing the specific feature. However, unit testing is performed during the coding stage and before the integration test.

Read More

How to build GraphQL API with Django – 7 Steps

What is GraphQL?

Technology is evolving so fast. Every day, old technologies are being replaced by new ones. For many years, REST architecture was dominating web services and APIS. In 2012, Facebook developed GraphQL and open-sourced it in 2015. Since then, it is becoming so popular in the development world. GraphQL is a declarative, strongly typed, data-driven query language to build APIs.

With GraphQL, you can ask exactly what you need from the server with a single API endpoint. Moreover, It aggregates data from multiple related tables and sources going as much deep as needed. In addition, with a strong type checking mechanism, GraphQL helps developers to write more reliable, robust and bug-free codes.

Read More

Powered by WordPress & Theme by Anders Norén