<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kracekumar</title>
    <description>The latest articles on DEV Community by Kracekumar (@kracekumar).</description>
    <link>https://dev.to/kracekumar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F656289%2Fcdebf457-2836-42a2-bb1c-a26be242ad7d.jpeg</url>
      <title>DEV Community: Kracekumar</title>
      <link>https://dev.to/kracekumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kracekumar"/>
    <language>en</language>
    <item>
      <title>Profiling Django App</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 17 Oct 2021 04:07:52 +0000</pubDate>
      <link>https://dev.to/kracekumar/profiling-django-app-3l6a</link>
      <guid>https://dev.to/kracekumar/profiling-django-app-3l6a</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9P22SCa---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/tracing.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9P22SCa---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/tracing.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  TL:DR
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://pyinstrument.readthedocs.io/en/latest/home.html"&gt;Pyinstrument&lt;/a&gt; is a call stack sampling profiler with low overhead to find out time spent in your Django application.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/bradmontgomery/django-querycount"&gt;QueryCount&lt;/a&gt; is a simplistic ORM query count middleware that counts the number of ORM queries, finds duplicate queries, and prints them in the terminal.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/jazzband/django-silk"&gt;Django Silk&lt;/a&gt; is an extensive Django profiler that records the entire execution, SQL queries, source of origin, and persists the recordings. The complete Django profiler.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🔬 What's Profiling? 🔬
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Profiling_(computer_programming)"&gt;Profiling&lt;/a&gt; is a dynamic program analysis that measures a running program's time and(or) memory consumption. The profiler can instrument the entire running program or record samples for a fixed duration of time.&lt;/p&gt;

&lt;h1&gt;
  
  
  🚀 Why Profile Django code? 🚀
&lt;/h1&gt;

&lt;p&gt;The Django application can consume more than expected memory or time. The blog post will focus on profiling performance. Some of the reasons why Django App can be slow&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ORM could be making &lt;a href="https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping"&gt;N+1 select queries&lt;/a&gt;. Example: The child model fetching parent models.&lt;/li&gt;
&lt;li&gt;The custom python code can be making DB queries inside a for-loop.&lt;/li&gt;
&lt;li&gt;The service or utility function may be making an HTTP or network call that consumes a lot of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Application Setup
&lt;/h1&gt;

&lt;p&gt;Here is a sample book counter application that contains three models - Book, Author, and Shelf. A shelf contains a list of books. A book has many authors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Models
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# book/models.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;middle_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;profile_photo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cover_photo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;#shelf/models.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="c1"&gt;# Create your models here.
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;book.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;db_index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManyToManyField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"shelves"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Views
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#shelf/views.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShelfViewSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewsets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ViewSet&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;http_method_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;queryset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Shelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ShelfSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Serializers
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#book/serializers.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;book.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelSerializer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"middle_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"profile_photo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelSerializer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AuthorSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cover_photo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"authors"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#shelf/serializers.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;shelf.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Shelf&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;book.serializers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BookSerializer&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;classic_books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'War And Peace'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Lolita'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'The Stranger'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShelfSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelSerializer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BookSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Shelf&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_representation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;to_representation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;classic_books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'is_classic'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'is_classic'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application has an endpoint &lt;code&gt;/shelf/&lt;/code&gt; that returns all the shelves along with books and authors using DRF model serializer.&lt;/p&gt;

&lt;h1&gt;
  
  
  🚆 Pyinstrument 🚆
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tTg2C06---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/joerick/pyinstrument/main/docs/img/screenshot.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTg2C06---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/joerick/pyinstrument/main/docs/img/screenshot.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pyinstrument.readthedocs.io/en/latest/home.html"&gt;Pyinstrument&lt;/a&gt; is a call stack Python profiler to find performance bottlenecks in your Python programs. It doesn't track every function call but samples the call stack every one millisecond. So it's a statistical profiler(not tracer), and it may lead to optimizing the wrong part of the program.&lt;/p&gt;

&lt;p&gt;Since the profiler records the call stack, every fixed interval(can be configured to lower value too, say 1ns) has a low overhead. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Profiling time = program execution time + profiler recording time&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the program takes &lt;code&gt;0.33s&lt;/code&gt; to run, pyinstrument profiling takes 0.43s (30% extra) , cProfile takes 0.61s (84% extra). &lt;/p&gt;

&lt;p&gt;Pyinstrument is a Python profiler that offers a Django middleware to record the profiling.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pyinstrument middleware records the request-response time. The middleware class goes into &lt;code&gt;MIDDLEWARE&lt;/code&gt; list variable. &lt;code&gt;MIDDLEWARE+=[ 'pyinstrument.middleware.ProfilerMiddleware'].&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The profiler stores the data in the configured directory mentioned in setting file. The profiler generates profile data for every request. The &lt;code&gt;PYINSTRUMENT_PROFILE_DIR&lt;/code&gt; contains a directory that stores the profile data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GGlKvxGG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/pyinstrument_output.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GGlKvxGG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/pyinstrument_output.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;By default, pyinstrument produces HTML profile information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The right corner contains the metadata. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;SAMPLES - number of samples collected during the execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;DURATION - Total duration of the profiling.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The tree structure captures the flow of the code along with the time spent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each line is a frame that contains the duration, function/method name, file path, and line number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data = ShelfSerializer(qs, many=True).data in the views, took 2.09 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The profiler auto hides any standard library and third-party calls to provide a brief overview of the program call graph.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the profile, &lt;code&gt;sleep&lt;/code&gt; function inside the serializer takes most of the time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Upside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fast and easy to use. &lt;/li&gt;
&lt;li&gt;Requires no code modification other than configuring &lt;code&gt;settings variables&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Less overhead to measure performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Downside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The library can only collect Python code and not SQL queries executed during the request-response cycle.&lt;/li&gt;
&lt;li&gt;Since the library samples the call stack every one millisecond, there can be false positives. It's possible to configure the sample rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🧮 Django Query Count 🧮
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lg4_JJlR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bradmontgomery/django-querycount/61a380d98bc55e926c011367ecc2031102c3484c/screenshot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lg4_JJlR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bradmontgomery/django-querycount/61a380d98bc55e926c011367ecc2031102c3484c/screenshot.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bradmontgomery/django-querycount"&gt;Django QueryCount&lt;/a&gt; is a middleware that prints the number of database queries made during the request processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;querycount.middleware.QueryCountMiddleware&lt;/code&gt; to the &lt;code&gt;MIDDLEWARE&lt;/code&gt; settings variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The middleware supports printing duplicate queries. Following are some extra settings options.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;QUERYCOUNT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s"&gt;'THRESHOLDS'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s"&gt;'MEDIUM'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;'HIGH'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;'MIN_TIME_TO_LOG'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;'MIN_QUERY_COUNT_TO_LOG'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s"&gt;'IGNORE_REQUEST_PATTERNS'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
      &lt;span class="s"&gt;'IGNORE_SQL_PATTERNS'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
      &lt;span class="s"&gt;'DISPLAY_DUPLICATES'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'RESPONSE_HEADER'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'X-DjangoQueryCount-Count'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ouptut
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# output in the server console&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;17/Oct/2021 11:05:43] &lt;span class="s2"&gt;"GET /shelf/ HTTP/1.1"&lt;/span&gt; 200 1031

http://localhost:8000/shelf/
|------|-----------|----------|----------|----------|------------|
| Type | Database  |   Reads  |  Writes  |  Totals  | Duplicates |
|------|-----------|----------|----------|----------|------------|
| RESP |  default  |    8     |    0     |    8     |     1      |
|------|-----------|----------|----------|----------|------------|
Total queries: 8 &lt;span class="k"&gt;in &lt;/span&gt;2.0803s


Repeated 1 times.
SELECT &lt;span class="s2"&gt;"book_book"&lt;/span&gt;.&lt;span class="s2"&gt;"id"&lt;/span&gt;, &lt;span class="s2"&gt;"book_book"&lt;/span&gt;.&lt;span class="s2"&gt;"name"&lt;/span&gt;,
&lt;span class="s2"&gt;"book_book"&lt;/span&gt;.&lt;span class="s2"&gt;"cover_photo"&lt;/span&gt;, &lt;span class="s2"&gt;"book_book"&lt;/span&gt;.&lt;span class="s2"&gt;"language"&lt;/span&gt; FROM &lt;span class="s2"&gt;"book_book"&lt;/span&gt;
INNER JOIN &lt;span class="s2"&gt;"shelf_shelf_books"&lt;/span&gt; ON &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"book_book"&lt;/span&gt;.&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="s2"&gt;"shelf_shelf_books"&lt;/span&gt;.&lt;span class="s2"&gt;"book_id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; WHERE &lt;span class="s2"&gt;"shelf_shelf_books"&lt;/span&gt;.&lt;span class="s2"&gt;"shelf_id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
1


Repeated 1 times.
SELECT &lt;span class="s2"&gt;"shelf_shelf"&lt;/span&gt;.&lt;span class="s2"&gt;"id"&lt;/span&gt;, &lt;span class="s2"&gt;"shelf_shelf"&lt;/span&gt;.&lt;span class="s2"&gt;"name"&lt;/span&gt; FROM &lt;span class="s2"&gt;"shelf_shelf"&lt;/span&gt;

&lt;span class="c"&gt;# output in the client&lt;/span&gt;
&lt;span class="nv"&gt;$http&lt;/span&gt; http://localhost:8000/shelf/ &lt;span class="nt"&gt;--header&lt;/span&gt;
HTTP/1.1 200 OK
Allow: GET
Content-Length: 1031
Content-Type: application/json
Date: Sun, 17 Oct 2021 11:05:43 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.9.7
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-DjangoQueryCount-Count: 8
X-Frame-Options: DENY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The middleware records the total number of SQL queries made and prints it in a tabular form in the terminal. &lt;/li&gt;
&lt;li&gt;The table contains the total number of reads, total number of writes, total queries, and total duplicates. The number of duplicates is a good indicator of N + 1 select queries.&lt;/li&gt;
&lt;li&gt;When DISPLAY_DUPLICATES is True, the middleware prints the duplicate query.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Upside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Simple to use.&lt;/li&gt;
&lt;li&gt;Fast and accurate.&lt;/li&gt;
&lt;li&gt;Low overhead to find out the SQL queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Downside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Simple, hence hard to find the origin of the SQL queries.&lt;/li&gt;
&lt;li&gt;No option to print all the SQL queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🔥 Django Silk 🔥
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xSUL7CQP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/jazzband/django-silk/master/screenshots/1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xSUL7CQP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/jazzband/django-silk/master/screenshots/1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/jazzband/django-silk"&gt;Silk&lt;/a&gt; is a live profiling and inspection tool for the Django framework. Silk intercepts and stores HTTP requests and database queries before presenting them in a user interface for further inspection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/jazzband/django-silk.git#egg&lt;span class="o"&gt;=&lt;/span&gt;django-silk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The latest PyPI version doesn't support Django 3.2.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;'silk.middleware.SilkyMiddleware'&lt;/code&gt; to &lt;code&gt;MIDDLEWARE&lt;/code&gt; settings variable.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;silk&lt;/code&gt; to &lt;code&gt;INSTALLED_APPS&lt;/code&gt; settings variable.&lt;/li&gt;
&lt;li&gt;Add silk endpoints to url patterns. &lt;code&gt;urlpatterns += [url(r'^silk/', include('silk.urls', namespace='silk'))]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;migrate&lt;/code&gt; to create tables. &lt;code&gt;python manage.py migrate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;collectstatic&lt;/code&gt; to collect static files, &lt;code&gt;python manage.py collectstatic&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Hvcu02H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Hvcu02H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_dashboard.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/silk/&lt;/code&gt; endpoint is the dashboard and lists all the recorded requests.&lt;/li&gt;
&lt;li&gt;The quick view under &lt;code&gt;Most Time Overall&lt;/code&gt; shows, the &lt;code&gt;response status, total response time, total time spent in queries, and total number of queries&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kyS0VilX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_details.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kyS0VilX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_details.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicking on the request profile takes to the detail view. The detail view displays &lt;code&gt;request headers details, response headers, and details on how to use the client to connect to the endpoint&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pzoH6Cgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_sql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pzoH6Cgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_sql.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The SQL tab displays all the queries made during the request-response cycle. &lt;/li&gt;
&lt;li&gt;Clicking on the single query displays the &lt;code&gt;query plan and Python traceback&lt;/code&gt; to find the source of origin. &lt;code&gt;SILKY_ANALYZE_QUERIES&lt;/code&gt; variable controls the feature to analyze the SQL query. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fiRRN83P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_sql_detail.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fiRRN83P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_sql_detail.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Silk also provides option to generate Python profile code for a view or any Python function using a decorator or a context manager. Below is the modified view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;silk.profiling.profiler&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;silk_profile&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShelfViewSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewsets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ViewSet&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;http_method_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;queryset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Shelf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;silk_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Shelf list'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ShelfSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1-ifuoBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_profile_graph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1-ifuoBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/silk_profile_graph.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile tab displays the call graph and Python traceback. The page also shows the link to download ` profile file(.prof). &lt;a href="https://jiffyclub.github.io/snakeviz/"&gt;snakeviz&lt;/a&gt; is an excellent tool to visualize the profile data.&lt;/li&gt;
&lt;li&gt;Below is the profile visualized using snakeviz.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UmVnCn0x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/snakeviz_graph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UmVnCn0x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/profiling_django/snakeviz_graph.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snakeviz graph is visually pleasing and gives a breakdown of the function call based on time spent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic Profiling - Profile specific function or class during runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
  SILKY_DYNAMIC_PROFILING = [{&lt;br&gt;
      'module': 'shelf.views',&lt;br&gt;
      'function': 'ShelfViewSet.list'&lt;br&gt;
  }] &lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Silk can also display the time taken by the silk profiler. The setting variable &lt;code&gt;SILKY_META&lt;/code&gt; controls it. When set to True, the dashboard displays the time taken by silk in red color in the display card.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Upside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Exhaustive profiling option and completeness.&lt;/li&gt;
&lt;li&gt;UI dashboard to visualise and browse the profiling data.&lt;/li&gt;
&lt;li&gt;Storing all the data in the database helps to analyze performance improvement on the same endpoint over time.&lt;/li&gt;
&lt;li&gt;Highly customizable and extensible to profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Downside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The library is not well maintained, there are a lot of open issues, and the PyPI release doesn't support Django 3.2 version.&lt;/li&gt;
&lt;li&gt;A bit of a learning curve and a lot of configuration.&lt;/li&gt;
&lt;li&gt;It can be slow on slow endpoints since it stores all the details in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Performance is a feature that lets the user of the application perform certain types of operations quicker. The profiling tools help developers to measure the application's performance and make decisions accordingly.&lt;/p&gt;

&lt;p&gt;There are other Django/Python profilers, but these three profilers help measure and understand the Django application performance. Use these tools to make your Django application faster.&lt;/p&gt;



&lt;blockquote&gt;
&lt;br&gt;
&lt;p&gt;1. 🚀Profiling Django App 🚀- &lt;a href="https://t.co/EifIAiW8ba"&gt;&lt;/a&gt;&lt;a href="https://t.co/EifIAiW8ba"&gt;&lt;/a&gt;&lt;a href="https://t.co/EifIAiW8ba"&gt;https://t.co/EifIAiW8ba&lt;/a&gt;. In this blog post, I discuss three tools. &lt;a href="https://twitter.com/hashtag/Django?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#Django&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/Python?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#Python&lt;/a&gt;&lt;/p&gt;— kracekumar || கிரேஸ்குமார் (@kracetheking) &lt;a href="https://twitter.com/kracetheking/status/1449813820151513088?ref_src=twsrc%5Etfw"&gt;October 17, 2021&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt; 

&lt;h1&gt;
  
  
  Image Credits
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Foot Print Photo by &lt;a href="https://unsplash.com/@widenka?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Martin Widenka&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/foot-print?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;Pyinstrument cover image is from the source repository.&lt;/li&gt;
&lt;li&gt;Query Count cover image is from the repository.&lt;/li&gt;
&lt;li&gt;Django Silk cover image is from the repository.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>profiling</category>
    </item>
    <item>
      <title>Generate HTTP Request</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 10 Oct 2021 18:33:27 +0000</pubDate>
      <link>https://dev.to/kracekumar/generate-http-request-576k</link>
      <guid>https://dev.to/kracekumar/generate-http-request-576k</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vskU7TgX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/HTTP_logo.svg/2880px-HTTP_logo.svg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vskU7TgX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/HTTP_logo.svg/2880px-HTTP_logo.svg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://httpie.io/cli"&gt;HTTPie&lt;/a&gt; is a command-line utility for making HTTP requests with more straightforward syntax(controversial, I agree). The interesting feature is &lt;code&gt;--offline&lt;/code&gt; flag which prints HTTP raw request text. The client sends the HTTP request to the server, and the server responds to the request. It's an alternate to &lt;a href="https://curl.se/"&gt;curl&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Syntax
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"&gt;HTTP Flow and syntrax from Wikipedia.&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A client sends &lt;em&gt;request messages&lt;/em&gt; to the server, which consist of&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a request line, consisting of the case-sensitive request method, a &lt;a href="https://en.wikipedia.org/wiki/Space_(punctuation)"&gt;space&lt;/a&gt;, the request target, another space, the protocol version, a &lt;a href="https://en.wikipedia.org/wiki/Carriage_return"&gt;carriage return&lt;/a&gt;, and a &lt;a href="https://en.wikipedia.org/wiki/Line_feed"&gt;line feed&lt;/a&gt; (e.g. &lt;em&gt;GET /images/logo.png HTTP/1.1&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;zero or more &lt;a href="https://en.wikipedia.org/wiki/HTTP_request_header_field"&gt;request header fields&lt;/a&gt;, each consisting of the case-insensitive field name, a colon, optional leading &lt;a href="https://en.wikipedia.org/wiki/Whitespace_(computer_science)"&gt;whitespace&lt;/a&gt;, the field value, and optional trailing whitespace (e.g. &lt;em&gt;Accept-Language: en&lt;/em&gt;), and ending with a carriage return and a line feed.&lt;/li&gt;
&lt;li&gt;an empty line, consisting of a carriage return and a line feed;&lt;/li&gt;
&lt;li&gt;an optional &lt;a href="https://en.wikipedia.org/wiki/HTTP_message_body"&gt;message body&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In the HTTP/1.1 protocol, all header fields except &lt;em&gt;Host&lt;/em&gt; are optional.&lt;/li&gt;
&lt;li&gt;A request line containing only the path name is accepted by servers to maintain compatibility with HTTP clients before the HTTP/1.0 specification in &lt;a href="https://en.wikipedia.org/wiki/RFC_(identifier)"&gt;RFC&lt;/a&gt; &lt;a href="https://datatracker.ietf.org/doc/html/rfc1945"&gt;1945&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Throughout the post, I'll use &lt;code&gt;--offline&lt;/code&gt; feature to understand how the HTTP request structure looks for educational purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🉑 Accept only JSON response data 🉑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HTTPie uses &lt;code&gt;:&lt;/code&gt; to separate header key and values in the terminal. &lt;code&gt;Accept:application/json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Accept&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept"&gt;header tells the server, the client accepts only specific MIME types, here &lt;code&gt;JSON&lt;/code&gt;. &lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt; httpbin.org/get Accept:application/json
GET /get HTTP/1.1
Accept: application/json
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Connection: keep-alive
Host: httpbin.org
User-Agent: HTTPie/2.5.0
&lt;span class="c"&gt;# Sample request sent to the server&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;http httpbin.org/get Accept:application/json
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: &lt;span class="nb"&gt;true
&lt;/span&gt;Access-Control-Allow-Origin: &lt;span class="k"&gt;*&lt;/span&gt;
Connection: keep-alive
Content-Length: 310
Content-Type: application/json
Date: Sun, 10 Oct 2021 07:21:40 GMT
Server: gunicorn/19.9.0

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Accept"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Accept-Encoding"&lt;/span&gt;: &lt;span class="s2"&gt;"gzip, deflate"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Host"&lt;/span&gt;: &lt;span class="s2"&gt;"httpbin.org"&lt;/span&gt;,
        &lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;: &lt;span class="s2"&gt;"HTTPie/2.5.0"&lt;/span&gt;,
        &lt;span class="s2"&gt;"X-Amzn-Trace-Id"&lt;/span&gt;: &lt;span class="s2"&gt;"Root=1-61629484-3b25a3631e2a89bf60f2600e"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"origin"&lt;/span&gt;: &lt;span class="s2"&gt;"xxx.xxx.xxx.xxx"&lt;/span&gt;,
    &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"http://httpbin.org/get"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can pass more than one value in the &lt;code&gt;Accept&lt;/code&gt; header seperated by comma.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The response from the server contains &lt;code&gt;Content-Type&lt;/code&gt; as JSON. The server can choose to ignore the &lt;code&gt;Accept&lt;/code&gt; header.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📚 Request the Tamil language version of duckduckgo 📚
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Accept-Language&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language"&gt;header instructs the web server to deliver particluar language version of the page.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Here &lt;code&gt;Accept-Language&lt;/code&gt; is set to &lt;code&gt;ta&lt;/code&gt;. &lt;code&gt;ta&lt;/code&gt; is &lt;a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes"&gt;ISO 639-1 code.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt;  https://duckduckgo.com Accept-Language:ta
GET / HTTP/1.1
Accept: &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Accept-Language: ta
Connection: keep-alive
Host: duckduckgo.com
User-Agent: HTTPie/2.5.0

&lt;span class="nv"&gt;$http&lt;/span&gt;  https://duckduckgo.com Accept-Language:ta
HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Encoding: &lt;span class="nb"&gt;gzip
&lt;/span&gt;Content-Security-Policy: default-src &lt;span class="s1"&gt;'none'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; connect-src  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ https://duck.co &lt;span class="p"&gt;;&lt;/span&gt; manifest-src  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; media-src  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; script-src blob:  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="s1"&gt;'unsafe-inline'&lt;/span&gt; &lt;span class="s1"&gt;'unsafe-eval'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; font-src data:  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; img-src data:  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; style-src  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="s1"&gt;'unsafe-inline'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; object-src &lt;span class="s1"&gt;'none'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; worker-src blob: &lt;span class="p"&gt;;&lt;/span&gt; child-src blob:  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; frame-src blob:  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ &lt;span class="p"&gt;;&lt;/span&gt; form-action  https://duckduckgo.com https://&lt;span class="k"&gt;*&lt;/span&gt;.duckduckgo.com https://3g2upl4pq6kufc4m.onion/ https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/ https://spreadprivacy.com/ https://duck.co &lt;span class="p"&gt;;&lt;/span&gt; frame-ancestors &lt;span class="s1"&gt;'self'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; base-uri &lt;span class="s1"&gt;'self'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; block-all-mixed-content &lt;span class="p"&gt;;&lt;/span&gt;
Content-Type: text/html&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UTF-8
Date: Sat, 09 Oct 2021 21:44:33 GMT
ETag: W/&lt;span class="s2"&gt;"6161a338-16b8"&lt;/span&gt;
Expect-CT: max-age&lt;span class="o"&gt;=&lt;/span&gt;0
Expires: Sat, 09 Oct 2021 21:44:32 GMT
Permissions-Policy: interest-cohort&lt;span class="o"&gt;=()&lt;/span&gt;
Referrer-Policy: origin
Server: nginx
Strict-Transport-Security: max-age&lt;span class="o"&gt;=&lt;/span&gt;31536000
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;block

&amp;lt;&lt;span class="o"&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
...
&amp;lt;body &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"pg-index"&lt;/span&gt; &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"page-index body--home"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/tl5.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
&amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/lib/l123.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
&amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/locale/ta_IN/duckduckgo50.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
&amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/util/u588.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
&amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/d3012.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
...
&amp;lt;noscript&amp;gt;
    &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tag-home"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tag-home__wrapper"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tag-home__item"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                Privacy, simplified&amp;amp;period&lt;span class="p"&gt;;&lt;/span&gt;
                &amp;lt;span &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hide--screen-xs"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/about"&lt;/span&gt; &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tag-home__link"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; மேலும் கற்க&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/noscript&amp;gt;
...
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The header can carry more than one value separated by a comma.&lt;/li&gt;
&lt;li&gt;When more than one value is present, an extra parameter &lt;code&gt;q=0.5&lt;/code&gt; represents the weightage among the values. Example: &lt;code&gt;Accept-Language: ta,fr;q=0.50&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;One of the link description is in Tamil, &lt;code&gt;மேலும் கற்க&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔑 Post Authorization token as part of login 🔑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Authorization&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization"&gt;header can be used to provide credentials to authenticate the user&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;Authorization:"Bearer my-dear-darkness"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Because of space between Bearer and the value quotes is mandatory.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt; POST httpbin.org/auth Authorization:&lt;span class="s2"&gt;"Bearer my-dear-darkness"&lt;/span&gt;
POST /auth HTTP/1.1
Accept: &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Authorization: Bearer my-dear-darkness
Connection: keep-alive
Content-Length: 0
Host: httpbin.org
User-Agent: HTTPie/2.5.0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🍪 Send Cookie as part of a request 🍪
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The server can send HTTP Cookie as part of the response, and the client can send the Cookies in subsequent requests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Cookie&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization"&gt;header carries the cookies previously sent by the user.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Semi-colon separates multiple cookie pairs.&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;"name=not-unique;value=23"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt; http://pie.dev/cookies Cookie:&lt;span class="s2"&gt;"name=not-unique;value=23"&lt;/span&gt;
GET /cookies HTTP/1.1
Accept: &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Connection: keep-alive
Cookie: &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;not-unique&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;23
Host: dev.pie
User-Agent: HTTPie/2.5.0
&lt;span class="nv"&gt;$http&lt;/span&gt; http://pie.dev/cookies Cookie:&lt;span class="s2"&gt;"name=not-unique;value=23"&lt;/span&gt;
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 69be1b984c743c0c-BLR
Connection: keep-alive
Content-Encoding: &lt;span class="nb"&gt;gzip
&lt;/span&gt;Content-Type: application/json
Date: Sun, 10 Oct 2021 07:24:13 GMT
NEL: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"success_fraction"&lt;/span&gt;:0,&lt;span class="s2"&gt;"report_to"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Report-To: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"endpoints"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;a.nel.cloudflare.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;report&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v3?s=2Zt9wQcKQYStY5dPukoEXFwn7K6pKNaVTiKljZ5h9oL3mcQZj0khYq8Kmzo8PmQinPncStZeHASetQqHzCODe0wbrljPEIJxCWGdRWMbry9rWOG%2FBheDvJs7"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;,&lt;span class="s2"&gt;"group"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: &lt;span class="nb"&gt;true
&lt;/span&gt;access-control-allow-origin: &lt;span class="k"&gt;*&lt;/span&gt;
alt-svc: &lt;span class="nv"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-29&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-28&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-27&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"cookies"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"not-unique"&lt;/span&gt;,
        &lt;span class="s2"&gt;"value"&lt;/span&gt;: &lt;span class="s2"&gt;"23"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✉️ Send JSON Request ✉️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HTTPie supports sending form-encoded values or JSON values. &lt;code&gt;=&lt;/code&gt; sign indiciates JSON key-value pair.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;=&lt;/code&gt; is useful for primitive values like &lt;code&gt;number, string, null, boolean&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;lang-py&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt; PUT http://pie.dev/put &lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;py &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10
PUT /put HTTP/1.1
Accept: application/json, &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.5
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Connection: keep-alive
Content-Length: 33
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/2.5.0

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"lang"&lt;/span&gt;: &lt;span class="s2"&gt;"py"&lt;/span&gt;,
    &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.10"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$HTTP&lt;/span&gt;/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 69be1e017fb53c12-BLR
Connection: keep-alive
Content-Encoding: &lt;span class="nb"&gt;gzip
&lt;/span&gt;Content-Type: application/json
Date: Sun, 10 Oct 2021 07:25:52 GMT
NEL: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"success_fraction"&lt;/span&gt;:0,&lt;span class="s2"&gt;"report_to"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Report-To: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"endpoints"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;a.nel.cloudflare.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;report&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v3?s=GMW5PQHMwjxpVUeDG7uWo6M%2FiKLMzmQLd1e5BIG3AXljmuQgwCP9nzrFPdaidR2wL14eisfiViDhumDHpepgNB6yIrsVKXRybHa5tRqmH7lUDoQdRqCK1Ijg"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;,&lt;span class="s2"&gt;"group"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: &lt;span class="nb"&gt;true
&lt;/span&gt;access-control-allow-origin: &lt;span class="k"&gt;*&lt;/span&gt;
alt-svc: &lt;span class="nv"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-29&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-28&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-27&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;lang&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;py&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;3.10&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"form"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Accept"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json, */*;q=0.5"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Accept-Encoding"&lt;/span&gt;: &lt;span class="s2"&gt;"gzip"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cdn-Loop"&lt;/span&gt;: &lt;span class="s2"&gt;"cloudflare"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Connecting-Ip"&lt;/span&gt;: &lt;span class="s2"&gt;"49.207.222.139"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ipcountry"&lt;/span&gt;: &lt;span class="s2"&gt;"IN"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ray"&lt;/span&gt;: &lt;span class="s2"&gt;"69be1e017fb53c12-FRA"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Visitor"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;scheme&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Connection"&lt;/span&gt;: &lt;span class="s2"&gt;"Keep-Alive"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Length"&lt;/span&gt;: &lt;span class="s2"&gt;"33"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Host"&lt;/span&gt;: &lt;span class="s2"&gt;"pie.dev"&lt;/span&gt;,
        &lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;: &lt;span class="s2"&gt;"HTTPie/2.5.0"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"json"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"lang"&lt;/span&gt;: &lt;span class="s2"&gt;"py"&lt;/span&gt;,
        &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.10"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"origin"&lt;/span&gt;: &lt;span class="s2"&gt;"xxx.xxx.xxx.xxxx"&lt;/span&gt;,
    &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"http://pie.dev/put"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✉️ Send non-primitive JSON values ✉️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:=&lt;/code&gt; means the JSON value is non-primitve values like &lt;code&gt;array/list and dictionary&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Single quote carries the value.&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;os:='["GNU/Linux", "Mac OSX"]'&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt;  PUT http://pie.dev/put &lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;py &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10 os:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'["GNU/Linux", "Mac OSX"]'&lt;/span&gt;
PUT /put HTTP/1.1
Accept: application/json, &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.5
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Connection: keep-alive
Content-Length: 65
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/2.5.0

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"lang"&lt;/span&gt;: &lt;span class="s2"&gt;"py"&lt;/span&gt;,
    &lt;span class="s2"&gt;"os"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"GNU/Linux"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Mac OSX"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.10"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$http&lt;/span&gt;  PUT http://pie.dev/put &lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;py &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10 os:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'["GNU/Linux", "Mac OSX"]'&lt;/span&gt;
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 69be224ce97c3c0c-BLR
Connection: keep-alive
Content-Encoding: &lt;span class="nb"&gt;gzip
&lt;/span&gt;Content-Type: application/json
Date: Sun, 10 Oct 2021 07:28:48 GMT
NEL: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"success_fraction"&lt;/span&gt;:0,&lt;span class="s2"&gt;"report_to"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Report-To: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"endpoints"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;a.nel.cloudflare.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;report&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v3?s=dgY0R%2FqomBbumKs0IVB7GjPR2chhHJ9wVKAzW33IOnvZ%2Fs4l2LYnvKKeXo6Xhd162AYKGzyIrK4pNrYdH8SEs1NvGmYfJqEDIPmfUOELqpC6HK9iP1zIENa0"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;,&lt;span class="s2"&gt;"group"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: &lt;span class="nb"&gt;true
&lt;/span&gt;access-control-allow-origin: &lt;span class="k"&gt;*&lt;/span&gt;
alt-svc: &lt;span class="nv"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-29&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-28&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-27&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;lang&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;py&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;3.10&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;os&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;GNU/Linux&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Mac OSX&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]}"&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"form"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Accept"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json, */*;q=0.5"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Accept-Encoding"&lt;/span&gt;: &lt;span class="s2"&gt;"gzip"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cdn-Loop"&lt;/span&gt;: &lt;span class="s2"&gt;"cloudflare"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Connecting-Ip"&lt;/span&gt;: &lt;span class="s2"&gt;"49.207.222.139"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ipcountry"&lt;/span&gt;: &lt;span class="s2"&gt;"IN"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ray"&lt;/span&gt;: &lt;span class="s2"&gt;"69be224ce97c3c0c-FRA"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Visitor"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;scheme&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Connection"&lt;/span&gt;: &lt;span class="s2"&gt;"Keep-Alive"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Length"&lt;/span&gt;: &lt;span class="s2"&gt;"65"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Host"&lt;/span&gt;: &lt;span class="s2"&gt;"pie.dev"&lt;/span&gt;,
        &lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;: &lt;span class="s2"&gt;"HTTPie/2.5.0"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"json"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"lang"&lt;/span&gt;: &lt;span class="s2"&gt;"py"&lt;/span&gt;,
        &lt;span class="s2"&gt;"os"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"GNU/Linux"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Mac OSX"&lt;/span&gt;
        &lt;span class="o"&gt;]&lt;/span&gt;,
        &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.10"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"origin"&lt;/span&gt;: &lt;span class="s2"&gt;"xx.xxx.xxx.xxx"&lt;/span&gt;,
    &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"http://pie.dev/put"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📤 Upload files 📤
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; flag indicates the data is form-encoded values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@&lt;/code&gt; symbol indicates the value is a file. &lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;cv@hello-world.txt&lt;/code&gt;. &lt;code&gt;cv&lt;/code&gt; form field name.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$cat&lt;/span&gt; hello-world.txt
hello-world
&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; POST pie.dev/post &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Krace'&lt;/span&gt; cv@hello-world.txt
POST /post HTTP/1.1
Accept: &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;
Accept-Encoding: &lt;span class="nb"&gt;gzip&lt;/span&gt;, deflate
Connection: keep-alive
Content-Length: 277
Content-Type: multipart/form-data&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;boundary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;183f70d3da41432d95bcd839e2cc20e2
Host: pie.dev
User-Agent: HTTPie/2.5.0

&lt;span class="nt"&gt;--183f70d3da41432d95bcd839e2cc20e2&lt;/span&gt;
Content-Disposition: form-data&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;

Krace
&lt;span class="nt"&gt;--183f70d3da41432d95bcd839e2cc20e2&lt;/span&gt;
Content-Disposition: form-data&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hello-world.txt"&lt;/span&gt;
Content-Type: text/plain

hello-world

&lt;span class="nt"&gt;--183f70d3da41432d95bcd839e2cc20e2--&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;http &lt;span class="nt"&gt;-f&lt;/span&gt; POST pie.dev/post &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Krace'&lt;/span&gt; cv@hello-world.txt
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 69be2564a8fc3c0c-BLR
Connection: keep-alive
Content-Encoding: &lt;span class="nb"&gt;gzip
&lt;/span&gt;Content-Type: application/json
Date: Sun, 10 Oct 2021 07:30:54 GMT
NEL: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"success_fraction"&lt;/span&gt;:0,&lt;span class="s2"&gt;"report_to"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Report-To: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"endpoints"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;a.nel.cloudflare.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;report&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v3?s=yNaTSZJ7ouYH%2FSJZw6LIR5vNl6KNTFeDKF1u8V60abb3ClKLzdOj0zkchcIAWqTvZDbxXm5MnffDkCLdqviMQuAo7DqFA2GH%2Bm%2FiZ6sH90oOr0HyFGAuS4Gp"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;,&lt;span class="s2"&gt;"group"&lt;/span&gt;:&lt;span class="s2"&gt;"cf-nel"&lt;/span&gt;,&lt;span class="s2"&gt;"max_age"&lt;/span&gt;:604800&lt;span class="o"&gt;}&lt;/span&gt;
Server: cloudflare
Transfer-Encoding: chunked
access-control-allow-credentials: &lt;span class="nb"&gt;true
&lt;/span&gt;access-control-allow-origin: &lt;span class="k"&gt;*&lt;/span&gt;
alt-svc: &lt;span class="nv"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-29&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-28&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400, h3-27&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":443"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;ma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;86400

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
    &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"cv"&lt;/span&gt;: &lt;span class="s2"&gt;"hello-world&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"form"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Krace"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Accept"&lt;/span&gt;: &lt;span class="s2"&gt;"*/*"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Accept-Encoding"&lt;/span&gt;: &lt;span class="s2"&gt;"gzip"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cdn-Loop"&lt;/span&gt;: &lt;span class="s2"&gt;"cloudflare"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Connecting-Ip"&lt;/span&gt;: &lt;span class="s2"&gt;"49.207.222.139"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ipcountry"&lt;/span&gt;: &lt;span class="s2"&gt;"IN"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Ray"&lt;/span&gt;: &lt;span class="s2"&gt;"69be2564a8fc3c0c-FRA"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Cf-Visitor"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;scheme&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Connection"&lt;/span&gt;: &lt;span class="s2"&gt;"Keep-Alive"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Length"&lt;/span&gt;: &lt;span class="s2"&gt;"277"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;: &lt;span class="s2"&gt;"multipart/form-data; boundary=252c6fcd1dcc40e09de54958660d672d"&lt;/span&gt;,
        &lt;span class="s2"&gt;"Host"&lt;/span&gt;: &lt;span class="s2"&gt;"pie.dev"&lt;/span&gt;,
        &lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;: &lt;span class="s2"&gt;"HTTPie/2.5.0"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="s2"&gt;"json"&lt;/span&gt;: null,
    &lt;span class="s2"&gt;"origin"&lt;/span&gt;: &lt;span class="s2"&gt;"xxx.xxx.xxx.xxxx"&lt;/span&gt;,
    &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"http://pie.dev/post"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://httpie.io/"&gt;Explore more in HTTPie website.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🐈 How to verify the the generated request works? 🐈
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Netcat"&gt;Netcat&lt;/a&gt; is a utility for sending and receiving data in network connection using TCP or UDP. Netcat take hostname, port, and body as arguments and sends it to the server and displays the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$http&lt;/span&gt; &lt;span class="nt"&gt;--offline&lt;/span&gt;  PUT http://httpbin.org/put &lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;py &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10 os:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'["GNU/Linux", "Mac OSX"]'&lt;/span&gt; | nc httpbin.org 80
HTTP/1.1 200 OK
Date: Sun, 10 Oct 2021 08:27:58 GMT
Content-Type: application/json
Content-Length: 631
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: &lt;span class="k"&gt;*&lt;/span&gt;
Access-Control-Allow-Credentials: &lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
  &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;lang&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;py&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;3.10&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;os&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;GNU/Linux&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Mac OSX&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]}"&lt;/span&gt;,
  &lt;span class="s2"&gt;"files"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
  &lt;span class="s2"&gt;"form"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
  &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Accept"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json, */*;q=0.5"&lt;/span&gt;,
    &lt;span class="s2"&gt;"Accept-Encoding"&lt;/span&gt;: &lt;span class="s2"&gt;"gzip, deflate"&lt;/span&gt;,
    &lt;span class="s2"&gt;"Content-Length"&lt;/span&gt;: &lt;span class="s2"&gt;"65"&lt;/span&gt;,
    &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json"&lt;/span&gt;,
    &lt;span class="s2"&gt;"Host"&lt;/span&gt;: &lt;span class="s2"&gt;"httpbin.org"&lt;/span&gt;,
    &lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;: &lt;span class="s2"&gt;"HTTPie/2.5.0"&lt;/span&gt;,
    &lt;span class="s2"&gt;"X-Amzn-Trace-Id"&lt;/span&gt;: &lt;span class="s2"&gt;"Root=1-6162a40e-34b9a83f40868b4a73e8fa09"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"json"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"lang"&lt;/span&gt;: &lt;span class="s2"&gt;"py"&lt;/span&gt;,
    &lt;span class="s2"&gt;"os"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"GNU/Linux"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Mac OSX"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.10"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"origin"&lt;/span&gt;: &lt;span class="s2"&gt;"xxx.xxx.xxx.xxx"&lt;/span&gt;,
  &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"http://httpbin.org/put"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Netcat doesn't support encrypted network connections.&lt;/p&gt;



&lt;blockquote&gt;
&lt;br&gt;
&lt;p&gt;❓How to understand what HTTP request the client sends to the server?&lt;br&gt;💡Use HTTPie &lt;code&gt;--offline&lt;/code&gt; feature to print the HTTP request.&lt;br&gt;&lt;br&gt;Details on how to send various HTTPie options in the blog post - &lt;a href="https://t.co/mIEG2FpBkP"&gt;&lt;/a&gt;&lt;a href="https://t.co/mIEG2FpBkP"&gt;&lt;/a&gt;&lt;a href="https://t.co/mIEG2FpBkP"&gt;https://t.co/mIEG2FpBkP&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/TIL?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#TIL&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/Python?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#Python&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/CLI?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#CLI&lt;/a&gt; &lt;a href="https://t.co/kBvfc9QQAt"&gt;pic.twitter.com/kBvfc9QQAt&lt;/a&gt;&lt;/p&gt;— kracekumar || கிரேஸ்குமார் (@kracetheking) &lt;a href="https://twitter.com/kracetheking/status/1447289495234105345?ref_src=twsrc%5Etfw"&gt;October 10, 2021&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt; 

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;HTTPie - &lt;a href="https://httpie.io/"&gt;https://httpie.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HTTPBin - &lt;a href="http://httpbin.org"&gt;http://httpbin.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NetCat - &lt;a href="https://en.wikipedia.org/wiki/Netcat"&gt;https://en.wikipedia.org/wiki/Netcat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HTTP MDN Docs: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HTTP Header Image: &lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/HTTP_logo.svg/2880px-HTTP_logo.svg.png"&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/HTTP_logo.svg/2880px-HTTP_logo.svg.png&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Type Check Your Django Application</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sat, 18 Sep 2021 12:33:27 +0000</pubDate>
      <link>https://dev.to/kracekumar/type-check-your-django-application-1gba</link>
      <guid>https://dev.to/kracekumar/type-check-your-django-application-1gba</guid>
      <description>&lt;p&gt;Recently, I gave a talk, &lt;strong&gt;Type Check your Django app&lt;/strong&gt; at two conferences - &lt;a href="https://ep2021.europython.eu/talks/BsaKGk4-type-check-your-django-app/" rel="noopener noreferrer"&gt;Euro Python 2021&lt;/a&gt; and &lt;a href="https://in.pycon.org/cfp/2021/proposals/type-check-your-django-app~ejRql/" rel="noopener noreferrer"&gt;PyCon India 2021&lt;/a&gt;. The talk was about adding Python &lt;a href="http://mypy-lang.org/" rel="noopener noreferrer"&gt;gradual typing&lt;/a&gt; to Django using third-party package &lt;a href="https://github.com/TypedDjango/django-stubs" rel="noopener noreferrer"&gt;Django-stubs&lt;/a&gt; focussed heavily around &lt;a href="https://docs.djangoproject.com/en/3.2/topics/db/models/" rel="noopener noreferrer"&gt;Django Models&lt;/a&gt;. The blog post is the write-up of the talk. Here is the &lt;a href="https://youtu.be/efs3RXaLJ4I" rel="noopener noreferrer"&gt;unofficial link recorded video of the PyCon India talk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the link to &lt;a href="https://slides.com/kracekumar/type-hints-in-django/fullscreen" rel="noopener noreferrer"&gt;PyCon India Slides&lt;/a&gt;. The slides to &lt;a href="https://slides.com/kracekumar/type-hints-in-django-euro-pycon-2021" rel="noopener noreferrer"&gt;Euro Python Talk&lt;/a&gt; (both slides are similar).&lt;/p&gt;

&lt;h1&gt;
  
  
  Gradual Typing
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fhighway.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fhighway.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@justjohnl?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;John Lockwood&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/city-junction?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Python from the 3.5 version onwards started supported optional static typing or gradual typing. Some parts of the source code contain type annotation, and some parts may have no type annotation. The python interpreter doesn't complain about the lack of type hints. The third-party library mypy does the type check.&lt;/p&gt;

&lt;p&gt;Throughout the post, the source code example follows Python 3.8+ syntax and Django version 3.2. By default, static type checker refers to mypy, even though there are other type checkers like pyre from Facebook and pylance/pyright from Microsoft.&lt;/p&gt;

&lt;h1&gt;
  
  
  Types
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Ffruits.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Ffruits.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@alschim?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alexander Schimmeck&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/many-objects?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  Types at Run Time
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;function&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;tuple&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python's in-built function &lt;a href="https://docs.python.org/3/library/functions.html#type" rel="noopener noreferrer"&gt;type&lt;/a&gt; returns the type of the argument. When the argument is &lt;code&gt;("127.0.0.1", 8000)&lt;/code&gt;  the function returns type as tuple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;not-found@example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QuerySet&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a Django filter method result, type functions returns the type as &lt;code&gt;django.db.models.query.QuerySet&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Types at Static Checker Time
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;

&lt;span class="nf"&gt;reveal_type&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to the &lt;code&gt;type&lt;/code&gt; function, the static type checker provides &lt;code&gt;reveal_type&lt;/code&gt; function returns the type of the argument during static type checker time. The function is not present during Python runtime but is part of mypy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;mypy&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Revealed&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; 
  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tuple[builtins.str, builtins.int]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reveal_type returns the type of the tuple as &lt;code&gt;Tuple[builtins.str, builtins.int]&lt;/code&gt;. &lt;strong&gt;The reveal_type function also returns the type of tuple elements. In contrast, the type function returns the object type at the first level.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# filename.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;

&lt;span class="nf"&gt;reveal_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;not-found@example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;mypy&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Revealed&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; 
  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.contrib.auth.models.UserManager
  [django.contrib.auth.models.User]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, on the result of Django's User object's filter method, &lt;code&gt;reveal_type&lt;/code&gt; returns the type as &lt;code&gt;UserManager[User]&lt;/code&gt;. Mypy is interested in the type of objects at all levels.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mypy config
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# mypy.ini
&lt;/span&gt;&lt;span class="py"&gt;exclude&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"[a-zA-Z_]+.migrations.|[a-zA-Z_]+.tests.|[a-zA-Z_]+.testing."&lt;/span&gt;

&lt;span class="py"&gt;allow_redefinition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;false&lt;/span&gt;

&lt;span class="py"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
  &lt;span class="err"&gt;mypy_django_plugin.main,&lt;/span&gt;

&lt;span class="nn"&gt;[mypy.plugins.django-stubs]&lt;/span&gt;
&lt;span class="py"&gt;django_settings_module&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"yourapp.settings"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://code.djangoproject.com/ticket/29299" rel="noopener noreferrer"&gt;Django project&lt;/a&gt; does not contain type annotation in the source code and not in road map. Mypy needs information to infer the Django source code types. The mypy configuration needs to know the Django Stubs' entry point and the Django project's settings. Pass Django stub plugins to plugins variable and settings file location of the Django project to Django stubs plugin as &lt;code&gt;django_settings_module&lt;/code&gt; variable in &lt;code&gt;mypy.plugins.django-stubs&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Annotation Syntax
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fleather-jacket.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fleather-jacket.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@lealea_leaa?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Lea Øchel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/jacket?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;

&lt;span class="c1"&gt;# Example variable annotation
&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1989&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Example annotation on input arguments 
# and return values
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Class/instance method annotation
&lt;/span&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
               &lt;span class="n"&gt;is_alive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_alive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_alive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type annotation can happen in three places.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;During variable declaration/definition. Example: &lt;code&gt;lang: str = "Python"&lt;/code&gt;. The grammar is &lt;code&gt;name: &amp;lt;type&amp;gt; = &amp;lt;value&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The function declaration with input arguments and return value types annotated. &lt;code&gt;sum(a: int, b: int) -&amp;gt; int&lt;/code&gt;. The function &lt;code&gt;sum&lt;/code&gt; input arguments annotation looks similar to variable annotation. The return value annotation syntax, &lt;code&gt;-&amp;gt;&lt;/code&gt; arrow mark followed by &lt;code&gt;return value type.&lt;/code&gt; In sum function definition, it's &lt;code&gt;-&amp;gt; int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The method declaration. The syntax is similar to annotating a function. The &lt;code&gt;self&lt;/code&gt; or &lt;code&gt;class&lt;/code&gt; argument needs no annotation since mypy understand the semantics of the declaration. Except &lt;code&gt;__init__&lt;/code&gt; method, when the function, method does return value, the explicit annotation should be &lt;code&gt;-&amp;gt; None&lt;/code&gt; .&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Annotating Django Code
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F5%2F5b%2FHTTP_logo.svg%2F2880px-HTTP_logo.svg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F5%2F5b%2FHTTP_logo.svg%2F2880px-HTTP_logo.svg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Views
&lt;/h1&gt;

&lt;p&gt;Django supports &lt;code&gt;class-based views&lt;/code&gt; and &lt;code&gt;function-based views&lt;/code&gt;. Since function and method annotations are similar, the example will focus on function-based views.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The view function takes in a &lt;code&gt;HttpRequest&lt;/code&gt; and returns a &lt;code&gt;HttpResponse&lt;/code&gt;. The annotating view function is straightforward after importing relevant classes from &lt;code&gt;django.http&lt;/code&gt; module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
               &lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# bad - not precise and not useful
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is another view function, &lt;code&gt;view_404&lt;/code&gt;. The function returns &lt;code&gt;HttpResponseFound&lt;/code&gt;- Http Status code 404. The return value annotation can take three possible values -  &lt;code&gt;HttpResponseNotFound, HttpResponse, object&lt;/code&gt;. The mypy accepts all three annotations as valid. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why and How? MRO
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.python.org/download/releases/2.3/mro/" rel="noopener noreferrer"&gt;Method Resolution Order(mro)&lt;/a&gt; is the linearization of multi-inheritance parent classes. To know the mro of a class, each class has a mro method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponseBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponseBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HTTPResponseNotFound&lt;/code&gt; inherits &lt;code&gt;HttpResponse&lt;/code&gt;, &lt;code&gt;HTTPResponse&lt;/code&gt; inherits &lt;code&gt;HttpResponseBase&lt;/code&gt;, &lt;code&gt;HttpResponseBase&lt;/code&gt; inherits &lt;code&gt;objects&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  LSP - Liskov substitution principle
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle" rel="noopener noreferrer"&gt;Liskov substitution principle&lt;/a&gt; states that in an object-oriented program, substituting a superclass object reference with an object of any of its subclasses, the program should not break.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HTTPResponseNotFound&lt;/code&gt; is a special class of &lt;code&gt;HTTPResponse&lt;/code&gt; and &lt;code&gt;object&lt;/code&gt;; hence mypy doesn't complain about the type mismatch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Django Models
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fstore-box.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fstore-box.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@jankolar?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jan Antonin Kolar&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/database?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  Create
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;question_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pub_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date published&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                  &lt;span class="n"&gt;pub_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Question&lt;/code&gt; is a Django model with two explicit fields: &lt;code&gt;question_text of CharField&lt;/code&gt; and &lt;code&gt;pub_date of DateTimeField&lt;/code&gt; . &lt;code&gt;create_question&lt;/code&gt; is a simple function that takes in &lt;code&gt;question_text&lt;/code&gt; as an argument and returns &lt;code&gt;Question&lt;/code&gt; instance. &lt;/p&gt;

&lt;p&gt;When the function returns an object, the return annotation should be the class's reference or the class's name as a string. &lt;/p&gt;

&lt;h3&gt;
  
  
  Read
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;get_question&lt;/code&gt; takes a string as an argument and filters the Question model, and returns the first instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Incompatible&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Optional[Any]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mypy is unhappy about the return type annotation. The type checker says the return value can be None or Question instance. But the annotation is Question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two solutions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Annotate the return type to specify None value. &lt;/li&gt;
&lt;li&gt;Typing module contains an &lt;code&gt;Optional&lt;/code&gt; type, which means None. The return value Optional[Question] means None type or Question type.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# mypy.ini
&lt;/span&gt;&lt;span class="n"&gt;strict_optional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, mypy runs in &lt;code&gt;strict mode&lt;/code&gt;. &lt;code&gt;strict_optional&lt;/code&gt; variable instructs mypy to ignore None type in the annotations(in the return value, in the variable assignment, ...). There are a lot of such &lt;a href="https://mypy.readthedocs.io/en/stable/config_file.html#none-and-optional-handling" rel="noopener noreferrer"&gt;config variables mypy&lt;/a&gt; to run in the lenient mode.&lt;/p&gt;

&lt;p&gt;The lenient configs values can help to get type coverage quicker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filter method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuerySet&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="nf"&gt;object &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="nf"&gt;object &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuerySet&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="nf"&gt;object &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="nf"&gt;object &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django object manager filter method returns a QuerySet and is iterable. All bulk read, and filter operations return Queryset.  QuerySet carries the same model instances. It's a box type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fplate-cup-cake.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fplate-cup-cake.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@alexandrakusper?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alexandra Kusper&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/box-with-cup-cake?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;text__startswith&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exclude_question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;text__startswith&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other object manager methods that return queryset are &lt;code&gt;all, reverse, order_by, distinct, select_for_update, prefetch_related, ...&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Aggregate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# use integer field in production
&lt;/span&gt;    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DecimalField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_digits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;decimal_places&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FloatField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;publisher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pubdate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The aggregate query is a way of summarizing the data to get a high-level understanding of the data. &lt;code&gt;Publisher&lt;/code&gt; model stores the data of the book publisher with &lt;code&gt;name&lt;/code&gt; as an explicit character field.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Book&lt;/code&gt; model contains six explicit model fields. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name - Character Field of maximum length 300&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pages&lt;/code&gt; - Integer Field&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;price&lt;/code&gt; - Decimal Field&lt;/li&gt;
&lt;li&gt;rating - Decimal Field of maximum 10 digits and minimum 2 decimal digits&lt;/li&gt;
&lt;li&gt;publisher - Foreign Key to Publisher Field&lt;/li&gt;
&lt;li&gt;Pubdate - Date Field
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_avg_price&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;avg_price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_avg_price&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;avg_price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;276.666666666667&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function &lt;code&gt;get_avg_price&lt;/code&gt; returns the average price of all the books. avg_price is a Django query expression in the aggregate method. From the &lt;code&gt;get_avg_price&lt;/code&gt; function output, the output value is a dictionary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_avg_price&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;avg_price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type annotation is simple here. The return value is a &lt;code&gt;dictionary&lt;/code&gt;. &lt;code&gt;dict[str, Decimal]&lt;/code&gt; is the return type annotation. The first type of argument(&lt;code&gt;str&lt;/code&gt;) in the dict specification is the dictionary's key's type. The second type of argument(&lt;code&gt;Decimal&lt;/code&gt;) is the value of the key, &lt;code&gt;Decimal&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Annotate Method
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Frecords.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Frecords.jpeg"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@josephtpearson?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Joseph Pearson&lt;/a&gt; on &lt;a href="https://unsplash.com/collections/47883473/old-things?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/3.2/ref/models/querysets/#annotate" rel="noopener noreferrer"&gt;From Django doc's on annotate queryset method&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Annotates each object in the &lt;code&gt;QuerySet&lt;/code&gt; with the provided list of &lt;a href="https://docs.djangoproject.com/en/3.2/ref/models/expressions/" rel="noopener noreferrer"&gt;query expressions&lt;/a&gt;. An expression may be a simple value, a reference to a field on the model (or any related models), or an aggregate expression (averages, sums, etc.) that has been computed over the objects that are related to the objects in the &lt;code&gt;QuerySet&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;book&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num_books&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;num_books__gt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;count_by_publisher&lt;/code&gt; function counts the books published by the publisher. The &lt;code&gt;print_pub function&lt;/code&gt; filters the publisher count based on the num_book function argument and prints the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;# after importing the function
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;print_pub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Penguin&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;vintage&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;print_pub&lt;/code&gt; prints publication house name and their books count. Next is adding an annotation to both the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections.abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Iterable&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PublishedBookCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="n"&gt;Iterable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PublishedBookCount&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
  &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;count_by_publisher&lt;/code&gt; returns more than one value, and the result is iterable. &lt;code&gt;TypedDict&lt;/code&gt; is useful when the dictionary contents keys are known in advance. The attribute names of the class are the key names(should be a string), and the value type is an annotation to the key. &lt;code&gt;count_by_publisher&lt;/code&gt; 's annotation is &lt;code&gt;Iterable[PublishedBookCount]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$# &lt;/span&gt;mypy output
scratch.py:46: error: Incompatible &lt;span class="k"&gt;return &lt;/span&gt;value 
    &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;got &lt;span class="s2"&gt;"QuerySet[Any]"&lt;/span&gt;, expected
&lt;span class="s2"&gt;"Iterable[PublishedBookCount]"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;Publisher.objects.annotate&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="nv"&gt;num_books&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Count&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"book"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
               ^
scratch.py:51: error: 
      &lt;span class="s2"&gt;"Iterable[PublishedBookCount]"&lt;/span&gt; has no attribute &lt;span class="s2"&gt;"filter"&lt;/span&gt;
       res &lt;span class="o"&gt;=&lt;/span&gt; count_by_publisher&lt;span class="o"&gt;()&lt;/span&gt;.filter&lt;span class="o"&gt;(&lt;/span&gt;
         &lt;span class="nv"&gt;num_books__gt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;num_books&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mypy found out two errors.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;error: Incompatible return value type (got "QuerySet[Any]", expected "Iterable[PublishedBookCount]")&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mypy says the &lt;code&gt;.annotate&lt;/code&gt; method returns &lt;code&gt;QuerySet[Any]&lt;/code&gt; whereas annotation says return type as  &lt;code&gt;Iterable[PublishedBookCount]&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Iterable[PublishedBookCount]" has no attribute "filter"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;print_pub&lt;/code&gt; uses return value from &lt;code&gt;count_by_publisher&lt;/code&gt; to filter the values. Since the return value is iterable and the filter method is missing, mypy complains.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to fix these two errors?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
   &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the return value annotation for &lt;code&gt;count_by_publisher&lt;/code&gt; to &lt;code&gt;QuerySet[Publisher]&lt;/code&gt; as suggested by mypy. Now the first error is fixed, but some other error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# mypy output&lt;/span&gt;
&lt;span class="nv"&gt;$mypy&lt;/span&gt; scratch.py
scratch.py:55: error: &lt;span class="s2"&gt;"Publisher"&lt;/span&gt; has 
      no attribute &lt;span class="s2"&gt;"num_books"&lt;/span&gt;
      print&lt;span class="o"&gt;(&lt;/span&gt;item.name, item.num_books&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django dynamically adds the &lt;code&gt;num_books&lt;/code&gt; attribute to the return QuerySet. The publisher model has one explicitly declared attribute name, and &lt;code&gt;num_books&lt;/code&gt; is nowhere declared, and mypy is complaining. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/typeddjango/django-stubs/pull/398" rel="noopener noreferrer"&gt;This was a bug in Django Stubs project and got fixed recently.&lt;/a&gt; The newer version of Django stubs provides a nice way to annotate the function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 - Recommended
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django_stubs_ext&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WithAnnotations&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TypedPublisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;WithAnnotations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TypedPublisher&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WithAnnotation&lt;/code&gt; takes two argument &lt;code&gt;the model&lt;/code&gt; and &lt;code&gt;TypedDict&lt;/code&gt; with on the fly fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 - Good solution
&lt;/h3&gt;

&lt;p&gt;Another solution is to create a new model &lt;code&gt;TypedPublisher&lt;/code&gt; inside &lt;code&gt;TYPE_CHECKING&lt;/code&gt; block, which is only visible to mypy during static type-checking time. The &lt;code&gt;TypedPublisher&lt;/code&gt; inherits &lt;code&gt;Publisher&lt;/code&gt; model and declares the &lt;code&gt;num_books&lt;/code&gt; attribute as Django field, Then mypy will not complain about the missing attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TYPE_CHECKING&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;TYPE_CHECKING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TypedPublisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;num_books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TypedPublisher&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Publisher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;book&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num_books&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;num_books__gt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;count_by_publisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The earlier solution is elegant and works with simple data-types, which group by/annotate returns.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Ftoolboard.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Ftoolboard.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Board Photo by &lt;a href="https://unsplash.com/@nina_mercado?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Nina Mercado&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/tool-box?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;It's hard to start annotation when the project has a significant amount of code because of the surface area and topics to learn. Except for Django ORM, most of the custom code in the project will be Python-specific data flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pyannotate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/dropbox/pyannotate" rel="noopener noreferrer"&gt;Pyannotate&lt;/a&gt; is a tool to auto-generate type hints for a given Python project. Pyannotate captures the static types during execution code and writes to an annotation file. &lt;a href="https://pypi.org/project/pytest-annotate/" rel="noopener noreferrer"&gt;Pytest-annotate&lt;/a&gt; is a pytest plugin to infer types during test time. In the anecdotal micro-benchmark, because of pytest-annotate, the tests take 2X time to complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 0 - Preparation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create your views here.
# annotate the return value
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_404_0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a simple python file with no type annotations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;polls.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.test&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RequestFactory&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;request_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestFactory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request_factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/index&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_view_404_0&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;request_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestFactory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request_factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/404&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;view_404_0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add relevant test cases for the files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1 - Invoking Pyannotate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mysite.settings"&lt;/span&gt; &lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; poetry run pytest &lt;span class="nt"&gt;-sv&lt;/span&gt; polls/tests.py &lt;span class="nt"&gt;--annotate-output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./annotations.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While running the pytest pass extra option, &lt;code&gt;--annotate-ouput&lt;/code&gt; to store the inferred annotations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2 - Apply the annotations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;$cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;annotations.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"polls/views.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"line"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"func_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type_comments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"(django.core.handlers.wsgi.WSGIRequest) -&amp;gt; 
          django.http.response.HttpResponse"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"samples"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"polls/views.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"line"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"func_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"view_404_0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type_comments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"(django.core.handlers.wsgi.WSGIRequest) -&amp;gt; 
          django.http.response.HttpResponseNotFound"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"samples"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the test, &lt;code&gt;annotations.json&lt;/code&gt; file contains the inferred annotations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$poetry&lt;/span&gt; run pyannotate &lt;span class="nt"&gt;--type-info&lt;/span&gt; ./annotations.json &lt;span class="nt"&gt;-w&lt;/span&gt; polls/views.py &lt;span class="nt"&gt;--py3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, apply the annotations from the &lt;code&gt;annotations.json&lt;/code&gt; to the source code in &lt;code&gt;pools/views.py&lt;/code&gt;. &lt;code&gt;--py3&lt;/code&gt; flag indicates, the type-annotations should follow Python 3 syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.handlers.wsgi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WSGIRequest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http.response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.http.response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WSGIRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_404_0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WSGIRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;HttpResponseNotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying the annotations, the file contains the available annotations and required imports. &lt;/p&gt;

&lt;p&gt;One major shortcoming of pyannotate is &lt;code&gt;types&lt;/code&gt; at test time, and runtime can be different. Example: Dummy Email Provider. That's what happened in the current case. Django tests don't use HTTPRequest, and the tests use &lt;code&gt;WSGIRequest&lt;/code&gt; the request argument type annotation is WSGIRequest.&lt;/p&gt;

&lt;p&gt;For edge cases like these, &lt;code&gt;pyannotate&lt;/code&gt; is better(run Django server as part of pyannotate) and infers the type correctly. &lt;/p&gt;

&lt;h2&gt;
  
  
  Python Typing Koans
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fknot.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fknot.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@justjohnl?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;John Lockwood&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/city-junction?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Demo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kracekumar/python-typing-koans" rel="noopener noreferrer"&gt;Python Typing Koans repository&lt;/a&gt; contains the standalone python programs to learn gradual typing in Python. The programs contain partial or no type hints. The learner will understand how type-checkers evaluate the types by adding type hints and fixing the existing type hints error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Fpython_typing_koans%2Fpython_callables.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Fpython_typing_koans%2Fpython_callables.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project contains koans for Python, Django, and Django Rest Framework. By removing the errors in each file, the learner will understand the typing concepts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fkoan_output.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkracekumar.com%2Fimages%2Ftype_check_django_app%2Fkoan_output.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kracekumar.com/post/python-typing-koans/" rel="noopener noreferrer"&gt;The detailed write up about the project in the blog post.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: Gradual Typing is evolving and not complete yet. For example, it's still hard to annotate decorators(python 3.10 release should make it easier), so it's hard to annotate all dynamic behaviors. Adding type-hints to a project comes with its own cost, and not all projects would need it.  &lt;/p&gt;

&lt;p&gt;I hope you learned about Python Django, and if you're using type-hints, I'd like to hear about it. &lt;/p&gt;

&lt;p&gt;If you're struggling with type-hints in your projects or need some advice I'll be happy to offer. Shoot me an email!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/kracekumar/kracekumar.gitlab.io/-/blob/master/content/post/type_check_your_django_app.md" rel="noopener noreferrer"&gt;Found a bug or typo, and have spare time to fix, send a PR and the file is here!&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Euro PyCon - &lt;a href="https://ep2021.europython.eu/talks/BsaKGk4-type-check-your-django-app/" rel="noopener noreferrer"&gt;https://ep2021.europython.eu/talks/BsaKGk4-type-check-your-django-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyCon India - &lt;a href="https://in.pycon.org/cfp/2021/proposals/type-check-your-django-app%7EejRql/" rel="noopener noreferrer"&gt;https://in.pycon.org/cfp/2021/proposals/type-check-your-django-app~ejRql/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mypy - &lt;a href="http://mypy-lang.org/" rel="noopener noreferrer"&gt;http://mypy-lang.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Django Stub - &lt;a href="https://github.com/TypedDjango/django-stubs" rel="noopener noreferrer"&gt;https://github.com/TypedDjango/django-stubs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Django Models - &lt;a href="https://docs.djangoproject.com/en/3.2/topics/db/models/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/3.2/topics/db/models/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Video recording - &lt;a href="https://youtu.be/efs3RXaLJ4I" rel="noopener noreferrer"&gt;https://youtu.be/efs3RXaLJ4I&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyCon India Slides - &lt;a href="https://slides.com/kracekumar/type-hints-in-django/fullscreen" rel="noopener noreferrer"&gt;https://slides.com/kracekumar/type-hints-in-django/fullscreen&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LSP - &lt;a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Liskov_substitution_principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Method Resolution Order - &lt;a href="https://www.python.org/download/releases/2.3/mro/" rel="noopener noreferrer"&gt;https://www.python.org/download/releases/2.3/mro/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mypy Config variables - &lt;a href="https://mypy.readthedocs.io/en/stable/config_file.html#none-and-optional-handling" rel="noopener noreferrer"&gt;https://mypy.readthedocs.io/en/stable/config_file.html#none-and-optional-handling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Django Stubs Annotate fix - &lt;a href="https://github.com/typeddjango/django-stubs/pull/398" rel="noopener noreferrer"&gt;https://github.com/typeddjango/django-stubs/pull/398&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pyannotate - &lt;a href="https://github.com/dropbox/pyannotate" rel="noopener noreferrer"&gt;https://github.com/dropbox/pyannotate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pytest-annotate - &lt;a href="https://pypi.org/project/pytest-annotate/" rel="noopener noreferrer"&gt;https://pypi.org/project/pytest-annotate/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python Typing Koans - &lt;a href="https://github.com/kracekumar/python-typing-koans" rel="noopener noreferrer"&gt;https://github.com/kracekumar/python-typing-koans&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python Typing Koans blog post - &lt;a href="https://kracekumar.com/post/python-typing-koans" rel="noopener noreferrer"&gt;https://kracekumar.com/post/python-typing-koans&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Images References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fruits Photo by &lt;a href="https://unsplash.com/@alschim?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alexander Schimmeck&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/many-objects?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Highway Photo by &lt;a href="https://unsplash.com/@justjohnl?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;John Lockwood&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/city-junction?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Leather Jacket Photo by &lt;a href="https://unsplash.com/@lealea_leaa?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Lea Øchel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/jacket?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cup cake Photo by &lt;a href="https://unsplash.com/@alexandrakusper?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alexandra Kusper&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/box-with-cup-cake?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tool Board Photo by &lt;a href="https://unsplash.com/@nina_mercado?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Nina Mercado&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/tool-box?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store Photo by &lt;a href="https://unsplash.com/@jankolar?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jan Antonin Kolar&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/database?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Knot Photo by &lt;a href="https://unsplash.com/@justjohnl?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;John Lockwood&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/city-junction?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Records Photo by &lt;a href="https://unsplash.com/@josephtpearson?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Joseph Pearson&lt;/a&gt; on &lt;a href="https://unsplash.com/collections/47883473/old-things?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Discussions
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Lobste.rs - &lt;a href="https://lobste.rs/s/exvuuc/type_check_your_django_application" rel="noopener noreferrer"&gt;https://lobste.rs/s/exvuuc/type_check_your_django_application&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hacker News - &lt;a href="https://news.ycombinator.com/item?id=28640033" rel="noopener noreferrer"&gt;https://news.ycombinator.com/item?id=28640033&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reddit - &lt;a href="https://www.reddit.com/r/Python/comments/pufsg7/type_check_your_django_app/" rel="noopener noreferrer"&gt;r/python&lt;/a&gt; and &lt;a href="https://www.reddit.com/r/django/comments/pufsxm/type_check_your_django_application/" rel="noopener noreferrer"&gt;r/Django&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter Thread - &lt;a href="https://twitter.com/kracetheking/status/1441329460754595846" rel="noopener noreferrer"&gt;https://twitter.com/kracetheking/status/1441329460754595846&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;blockquote&gt;
&lt;p&gt;1/3. Blog Post of &lt;a href="https://twitter.com/pyconindia?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;@pyconindia&lt;/a&gt; and &lt;a href="https://twitter.com/europython?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;@europython&lt;/a&gt; talk, Type Check your Django App is out. &lt;a href="https://t.co/hAWhBljSYD" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://t.co/hAWhBljSYD" rel="noopener noreferrer"&gt;https://t.co/hAWhBljSYD&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/Python?src=hash&amp;amp;ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;#Python&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/Django?src=hash&amp;amp;ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;#Django&lt;/a&gt;&lt;/p&gt;— kracekumar || கிரேஸ்குமார் (@kracetheking) &lt;a href="https://twitter.com/kracetheking/status/1441329460754595846?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;September 24, 2021&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some the django stubs bugs mentioned were captured during prepartion of the talk, while you're reading the blog post bug might be fixed.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>types</category>
    </item>
    <item>
      <title>Markdown Backticks: TIL</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 22 Aug 2021 18:07:27 +0000</pubDate>
      <link>https://dev.to/kracekumar/markdown-backticks-til-4fcf</link>
      <guid>https://dev.to/kracekumar/markdown-backticks-til-4fcf</guid>
      <description>&lt;p&gt;In markdown spec, content between triple back ticks "&lt;br&gt;
&lt;br&gt;
```" is a code fence/code block. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
var = "this is a python variable"


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;According to &lt;a href="https://dev.toGithub%20Flavored%20Markdown"&gt;GFM&lt;/a&gt; and &lt;a href="https://koaning.io/til/2021-08-20-markdown-ticks/"&gt;this blog post&lt;/a&gt;, it's possible to have more than three backpacks as long followed by code and equal number of backticks. It's valid to have four backticks and five backticks. What's the use case?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
`markdown

### Markdown content

```python

print("Hell of a boring life")

```
### Closing thoughts


`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: dev.to doesn't render four backticks properly(mostly they may not follow GFM).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From GFM Spec&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The closing code fence must be at least as long as the opening fence: &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.github.com/gfm/#example-94"&gt;Source&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The outer block can be one type and inner codeblock can be another type. Say, outer block can be markdown and inner block can be &lt;code&gt;Python&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Preview from &lt;a href="https://dillinger.io/"&gt;https://dillinger.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jI5W8Bmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://til.kracekumar.com/images/markdown/markdown_preview_4_backticks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jI5W8Bmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://til.kracekumar.com/images/markdown/markdown_preview_4_backticks.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preview from Github&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aBeG3oZ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://til.kracekumar.com/images/markdown/gh_preview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aBeG3oZ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://til.kracekumar.com/images/markdown/gh_preview.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post initially appeared in my website &lt;a href="https://til.kracekumar.com/posts/markdown_backtick/"&gt;https://til.kracekumar.com/posts/markdown_backtick/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.github.com/gfm/#example-94"&gt;GFM Specs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://koaning.io/til/2021-08-20-markdown-ticks/"&gt;TIL Koaning Markdown tricks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>markdown</category>
      <category>todayilearned</category>
      <category>githubflavoredmarkdown</category>
    </item>
    <item>
      <title>Python Typing Koans</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 27 Jun 2021 10:30:00 +0000</pubDate>
      <link>https://dev.to/kracekumar/python-typing-koans-41gd</link>
      <guid>https://dev.to/kracekumar/python-typing-koans-41gd</guid>
      <description>&lt;p&gt;Python 3 introduced type annotation syntax. &lt;a href="https://www.python.org/dev/peps/pep-0484/"&gt;PEP 484&lt;/a&gt; introduced a provisional module to provide these standard definitions and tools, along with some conventions for situations where annotations are not available.&lt;/p&gt;

&lt;p&gt;Python is a dynamic language and follows gradual typing. When a static type checker runs a python code, the type checker considers code without type hints as &lt;code&gt;Any&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def print_name(name):
       print(name)

planet: str = "earth"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the &lt;code&gt;name&lt;/code&gt; argument type hint will be &lt;code&gt;Any&lt;/code&gt; since the type hint is missing while the type hint for the &lt;code&gt;planet&lt;/code&gt; variable is a string.&lt;/p&gt;

&lt;p&gt;Gradual typing is still an emerging topic in Python, and there is a gap in resources to educate the Python developers about the utility and Python typing concepts.&lt;/p&gt;

&lt;p&gt;On the surface, it looks easy to annotate the code. But the dynamic nature makes a certain part of the code harder to annotate. I have been using type-hints over the past three years and find it hard sometimes. A lot of new developers also face the same problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Koans
&lt;/h2&gt;

&lt;p&gt;To make the learning easier, simpler, I have created a &lt;a href="https://github.com/kracekumar/python-typing-koans"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The repository contains the standalone python programs. The programs contain partial or no type hints. By adding new type hints and fixing the existing type hints, the learner will understand how type-checkers evaluate the types and what's a difference in types at run-time.&lt;/p&gt;

&lt;p&gt;Here is a simple demo to use of the command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asciinema.org/a/419119"&gt;https://asciinema.org/a/419119&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository. &lt;code&gt;git clone git@github.com:kracekumar/python-typing-koans.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install all the dependencies(advised to use Python Poetry, virtual env should also work.). &lt;code&gt;poetry install&lt;/code&gt;. It requires Python 3.9.4&lt;/li&gt;
&lt;li&gt;List all the koans using the command line program. &lt;code&gt;poetry run python cli.py list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pick up a file to learn.&lt;/li&gt;
&lt;li&gt;Run the file with the command line program. &lt;code&gt;poetry run python cli.py one koans/py/100-easy-variable-wrong-type.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Repeat the process till there are no type errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;One central missing part is how the learner will know to fix the type errors?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The comments in the files carry the links to relevant concepts, which aids the learner in understanding the ideas to use.&lt;/p&gt;

&lt;p&gt;Screenshots of a few koans&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OjkYBQPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/python_callables.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OjkYBQPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/python_callables.png" alt="Python Callables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K6GrKU7M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/protocol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K6GrKU7M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/protocol.png" alt="Easy Protocol"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l9CYx-45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/python_protocol_medium.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l9CYx-45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/python_protocol_medium.png" alt="Medium Protocol"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics
&lt;/h2&gt;

&lt;p&gt;Python topics covered are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primitive Types&lt;/li&gt;
&lt;li&gt;dictionaries - dict/typedict&lt;/li&gt;
&lt;li&gt;Callables&lt;/li&gt;
&lt;li&gt;Design pattern - factory pattern, the builder pattern&lt;/li&gt;
&lt;li&gt;Decorators&lt;/li&gt;
&lt;li&gt;Type Alias&lt;/li&gt;
&lt;li&gt;Protocol, classes, objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;20 Python programs(koans) help the learner to understand gradual typing. The filenames indicate the learning level like &lt;code&gt;easy, medium, and hard.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The repository also contains Django and Django Rest Framework examples.&lt;/p&gt;

&lt;p&gt;The Django koans teach the annotating &lt;code&gt;views, models, model methods, queryset methods like filter, all, annotate, aggregate, Q object&lt;/code&gt; etc..&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qMnG4nM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/django_annotate_aggregate.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qMnG4nM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/django_annotate_aggregate.png" alt="Django Annotate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QsYgrzMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/django_queryset.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QsYgrzMw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/django_queryset.png" alt="Django Queryset"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DRF koans teach how to annotate  &lt;code&gt;DRF serializers and DRF Views&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JVwJ8bOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/drf_view.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JVwJ8bOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/drf_view.png" alt="DRF View"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XlFG6N5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/drf_serializer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XlFG6N5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kracekumar.com/images/python_typing_koans/drf_serializer.png" alt="DRF Serializer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you face any issues while solving the koans, please open an issue in the Github repository; I'd happy to answer and explain the relevant concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PEP 484 - &lt;a href="https://www.python.org/dev/peps/pep-0484/"&gt;https://www.python.org/dev/peps/pep-0484/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github Repository - &lt;a href="https://github.com/kracekumar/python-typing-koans"&gt;https://github.com/kracekumar/python-typing-koans&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python typing documentation - &lt;a href="https://docs.python.org/3/library/typing.html"&gt;https://docs.python.org/3/library/typing.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The blog post first appeared in &lt;a href="https://kracekumar.com/post/python-typing-koans/"&gt;my blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Photo by &lt;a href="https://unsplash.com/@xavi_cabrera&amp;gt;Xavi%20Cabrera&amp;lt;/a&amp;gt;%20on%20&amp;lt;a%20href="&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>gradualtyping</category>
      <category>typehints</category>
    </item>
    <item>
      <title>Model Field - Django ORM Working - Part 2</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 27 Jun 2021 08:27:12 +0000</pubDate>
      <link>https://dev.to/kracekumar/model-field-django-orm-working-part-2-chc</link>
      <guid>https://dev.to/kracekumar/model-field-django-orm-working-part-2-chc</guid>
      <description>&lt;p&gt;The last post covered &lt;a href="https://dev.to/kracekumar/structure-django-orm-working-part-1-10ch"&gt;the structure of Django Model&lt;/a&gt;. This post covers how the model field works, what are the some important methods and functionality and properties of the field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping"&gt;Object-Relational Mapper&lt;/a&gt; is a technique of declaring, querying the database tables using Object relationship in the programming language. Here is a sample model declaration in Django.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;question_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pub_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'date published'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each class inherits from &lt;code&gt;models.Model&lt;/code&gt; becomes a table inside the SQL database unless explicitly marked as abstract. The &lt;code&gt;Question&lt;/code&gt; model becomes &lt;code&gt;&amp;lt;app_name&amp;gt;_question&lt;/code&gt; table in the database. &lt;code&gt;question_text&lt;/code&gt; and &lt;code&gt;pub_date&lt;/code&gt; become columns in the table. The properties of the each field are declared by instantiating the respective class. Below is the method resolution order for &lt;code&gt;CharField&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterLookupMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;CharField&lt;/code&gt; inherits &lt;code&gt;Field&lt;/code&gt; and &lt;code&gt;Field&lt;/code&gt; inherits &lt;code&gt;RegisterLookUpMixin&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-level role of Field class
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The role of field class is to map type of the field to SQL database type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Serialization - to convert the Python object into relevant SQL database value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DeSerialization - to convert the SQL database value into Python object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check declared validations at the field level and built-in checks before serializing the data. For example, in a &lt;code&gt;PositiveIntegerField&lt;/code&gt; the value should be greater than zero - built-in constraint.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Structure of Field Class
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Find out all the classes inheriting the Field
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__subclasses__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BooleanField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DecimalField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DurationField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FilePathField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FloatField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IPAddressField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenericIPAddressField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimeField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUIDField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSONField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;related&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RelatedField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SearchVectorField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SearchQueryField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;fernet_fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncryptedField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;enumchoicefield&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnumChoiceField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArrayField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hstore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HStoreField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RangeField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;fernet_fields&lt;/code&gt; is a third-party library which implements the &lt;code&gt;EncryptedField&lt;/code&gt; by inheriting the &lt;code&gt;Field&lt;/code&gt; class. Also these are high level fields. For example, Django implements other high-level fields which inherit the above fields.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;EmailField&lt;/code&gt; inherits the &lt;code&gt;CharField&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__subclasses__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommaSeparatedIntegerField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SlugField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contrib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;citext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CICharField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django_extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RandomCharField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;django_extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShortUUIDField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the &lt;code&gt;Field&lt;/code&gt; class initializer signature&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;span class="n"&gt;Init&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;verbose_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db_index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NOT_PROVIDED&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;,
    editable=True,
    serialize=True,
    unique_for_date=None,
    unique_for_month=None,
    unique_for_year=None,
    choices=None,
    help_text='',
    db_column=None,
    db_tablespace=None,
    auto_created=False,
    validators=(),
    error_messages=None,
)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Field&lt;/code&gt; initializer contains 22 arguments. Most of the arguments are related to SQL database column properties and rest of the arguments are for Django admin and model forms.&lt;/p&gt;

&lt;p&gt;For example, Django provides Admin interface to browse the database records and allows you to edit. &lt;code&gt;blank&lt;/code&gt; parameter determines whether the field is required while filling up data in the admin interface and custom form. &lt;code&gt;help_text&lt;/code&gt; field is used while display the form.&lt;/p&gt;

&lt;p&gt;The most commonly used fields are &lt;code&gt;max_length, unique, blank, null, db_index, validators, default, auto_created&lt;/code&gt;. &lt;code&gt;null&lt;/code&gt; attribute is a boolean type when set to &lt;code&gt;True&lt;/code&gt;, the allows null value while saving to the database. &lt;code&gt;db_index=True&lt;/code&gt; created a &lt;code&gt;B-Tree&lt;/code&gt; index on the column.  &lt;code&gt;default&lt;/code&gt; attribute stores the default value passed on to the database, when the value for the field is missing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;validators&lt;/code&gt; attribute contains list of validators passed on by the user and Django's internal validators. The function of the validator is to determine the value is valid or not.  For example, in our &lt;code&gt;question_text&lt;/code&gt; field declaration &lt;code&gt;max_length&lt;/code&gt; is set to &lt;code&gt;200&lt;/code&gt;. When the field value is greater than 200, Django raises &lt;code&gt;ValidationError&lt;/code&gt;.  &lt;code&gt;max_length&lt;/code&gt; attribute is useful only for text field and &lt;code&gt;MaxLengthValidator&lt;/code&gt; will be missing in non-text fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow_odd_validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;...:&lt;/span&gt;     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;...:&lt;/span&gt;         &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is not odd number'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...:&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;allow_odd_validator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allow_odd_validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinValueValidator&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1305fdac0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxValueValidator&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1305fda30&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# let's look into question_text field validators
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxLengthValidator&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x12e767fa0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as the validator function or custom class doesn't raise exception, the value is considered as &lt;code&gt;valid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The details of each field can found in the &lt;a href="https://docs.djangoproject.com/en/3.2/ref/models/fields/"&gt;Django model field reference&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Field Methods
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;inspect&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getmembers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;predicate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isfunction&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getmembers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;predicate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ismethod&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Field&lt;/code&gt; class consists of (along with inherited ones) 65 methods. Let's look at some of the important ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  to_python
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;to_python&lt;/code&gt; method is responsible to convert the value passed on to the model  during intialization. For example, &lt;code&gt;to_python&lt;/code&gt; for &lt;code&gt;IntegerField&lt;/code&gt; will convert the value to Python integer. The original value could be &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;float&lt;/code&gt;. Every field will override &lt;code&gt;to_python&lt;/code&gt; method. Here is an example of &lt;code&gt;to_python&lt;/code&gt; method invocation on an &lt;code&gt;IntegerField&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bound&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'23'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;23.56&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  get_db_prep_value
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;get_db_prep_value&lt;/code&gt; method is responsible to convert Python value to SQL database specific value. Each field may have a different implementation depending on field type. For example, &lt;code&gt;Postgres&lt;/code&gt; has a native &lt;code&gt;UUID&lt;/code&gt; type, whereas in &lt;code&gt;SQLite&lt;/code&gt; and &lt;code&gt;MySQL&lt;/code&gt; Django uses &lt;code&gt;varchar(32)&lt;/code&gt;. Here is the implementation for &lt;code&gt;get_db_prep_value&lt;/code&gt; from &lt;code&gt;UUIDField&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_db_prep_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prepared&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_native_uuid_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hex&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;connection&lt;/code&gt; is a Database Connection or Wrapper object of underlying database. Below is an example output from a &lt;code&gt;Postgres Connection&lt;/code&gt; and &lt;code&gt;SQLite Connection&lt;/code&gt; for uuid field check.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
    &lt;span class="p"&gt;...:&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionProxy&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x10e3c8970&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseFeatures&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1236a6a00&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_native_uuid_field&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionProxy&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x10fe3b4f0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseFeatures&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x110ba5d90&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_native_uuid_field&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing to note, Django uses &lt;code&gt;psycopg2&lt;/code&gt; driver for Postgres and it will take care of handling UUID specific to Postgres because UUID Python object needs to be converted to string or bytes before sending to the Postgres server.&lt;/p&gt;

&lt;p&gt;Similar to &lt;code&gt;get_db_prep_value&lt;/code&gt;, &lt;code&gt;get_prep_value&lt;/code&gt;  which converts Python value to &lt;code&gt;query value&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  formfield
&lt;/h3&gt;

&lt;p&gt;Django supports &lt;code&gt;ModelForm&lt;/code&gt; which is one to one mapping of HTML form to Django model. The Django admin uses &lt;code&gt;ModelForm&lt;/code&gt; . The form consists of several fields. Each field in the form maps to field in the model. So Django can automatically construct the form with a list of validators from the model field.&lt;/p&gt;

&lt;p&gt;Here is the implementation for the UUIDField.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;formfield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;formfield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'form_class'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUIDField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you create a custom database field, you need to create a custom form field to work with Django admin and pass it as an argument to super class method.&lt;/p&gt;

&lt;h3&gt;
  
  
  deconstruct
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;deconstruct&lt;/code&gt; method returns value for creating an exact copy of the field. The method returns a tuple with 4 values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first value is the &lt;code&gt;name&lt;/code&gt; of the field passed during initialisation. The default value is &lt;code&gt;None&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The import path of the field.&lt;/li&gt;
&lt;li&gt;The list of positonal arguments passed during the field creation.&lt;/li&gt;
&lt;li&gt;The dictionary of keyword arguments passed during the field creation.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# Let's see the question_text deconstruct method return value
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;question_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'django.db.models.CharField'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'max_length'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# let's create a new integer field with a name
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'int_field'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;allow_odd_validator&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'int_field'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'django.db.models.IntegerField'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;[],&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'validators'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allow_odd_validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;int_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;69&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_2_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;int_2_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'django.db.models.IntegerField'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also when you implement a custom field, you can override the deconstruct method. Here is the &lt;code&gt;deconstruct&lt;/code&gt; implementation for &lt;code&gt;UUIDField&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;deconstruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'max_length'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;init&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;__init__&lt;/code&gt; method is a good place to override some of the default values. For example, &lt;code&gt;UUIDField&lt;/code&gt; max_length should always be &lt;code&gt;32&lt;/code&gt; irrespective of the value passed on. In the decimal field, &lt;code&gt;max_digits&lt;/code&gt; can be modified during initialization.&lt;/p&gt;

&lt;p&gt;Here is the &lt;code&gt;UUIDField&lt;/code&gt; initializer method implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'max_length'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
    &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  db_type
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;db_type&lt;/code&gt; method takes Django connection as an argument and returns the database specific implementation type for this field. The method takes connection as an argument. Here is the output of db_type for Postgres and SQLite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# Postgres
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;uuid_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUIDField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;uuid_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;'uuid'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# Sqlite
&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;uuid_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUIDField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;uuid_field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rel_db_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;'char(32)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;get_internal_type&lt;/code&gt; method returns &lt;code&gt;internal&lt;/code&gt; Python type which is companion to the &lt;code&gt;db_type&lt;/code&gt; method. In practice, Django fields type and database field mapping is maintained as class variable in &lt;code&gt;DatabaseWrapper&lt;/code&gt;. You can find, &lt;a href="https://github.com/django/django/blob/main/django/db/backends/postgresql/base.py"&gt;Django fields and Postgres fields mapping in backends module&lt;/a&gt;. Below is the mapping taken from source code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseDatabaseWrapper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;vendor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'postgresql'&lt;/span&gt;
    &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'PostgreSQL'&lt;/span&gt;
    &lt;span class="c1"&gt;# This dictionary maps Field objects to their associated PostgreSQL column
&lt;/span&gt;    &lt;span class="c1"&gt;# types, as strings. Column-type strings can contain format strings; they'll
&lt;/span&gt;    &lt;span class="c1"&gt;# be interpolated against the values of Field.__dict__ before being output.
&lt;/span&gt;    &lt;span class="c1"&gt;# If a column type is set to None, it won't be included in the output.
&lt;/span&gt;    &lt;span class="n"&gt;data_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'AutoField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'serial'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'BigAutoField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'bigserial'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'BinaryField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'bytea'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'BooleanField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'boolean'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'CharField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'varchar(%(max_length)s)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'DateField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'DateTimeField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'timestamp with time zone'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'DecimalField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'numeric(%(max_digits)s, %(decimal_places)s)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'DurationField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'interval'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'FileField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'varchar(%(max_length)s)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'FilePathField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'varchar(%(max_length)s)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'FloatField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'double precision'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'IntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'BigIntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'bigint'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'IPAddressField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'inet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'GenericIPAddressField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'inet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'JSONField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'jsonb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'OneToOneField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'PositiveBigIntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'bigint'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'PositiveIntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'PositiveSmallIntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'smallint'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'SlugField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'varchar(%(max_length)s)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'SmallAutoField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'smallserial'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'SmallIntegerField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'smallint'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'TextField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'text'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'TimeField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'time'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'UUIDField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;get_internal_type&lt;/code&gt; values are keys and values are Postgres field names.&lt;/p&gt;

&lt;p&gt;I have skipped the implementation of the rest of the methods like &lt;code&gt;__reduce__&lt;/code&gt; and &lt;code&gt;check&lt;/code&gt; . You can go through the source code of Django fields in &lt;a href="https://github.com/django/django/blob/main/django/db/models/fields/__init__.py"&gt;GitHub&lt;/a&gt; and also you will find class variables and private methods usages.&lt;/p&gt;

&lt;p&gt;Django documentation has an excellent page on &lt;a href="https://docs.djangoproject.com/en/3.2/howto/custom-model-fields/"&gt;how-to write custom model field&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;models.Field&lt;/code&gt; is the root of all the model fields.&lt;/li&gt;
&lt;li&gt;Field initializer takes configuration details like &lt;code&gt;name, default, db_index, null&lt;/code&gt; for the database columns and &lt;code&gt;blank, help_text&lt;/code&gt; for non-column features like Django model form and Django admin.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__init__&lt;/code&gt; method in the child class can override the user passed value and(or) set custom default value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;validators&lt;/code&gt; attribute in the field contains the user-defined validators and default validators specific to the field.&lt;/li&gt;
&lt;li&gt;Every field needs to implement a few methods to work with the specific databases. Some of the useful methods are &lt;code&gt;to_python, get_db_prep_value, get_prep_value, deconstruct, formfield,  db_type&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Django &lt;code&gt;Connection&lt;/code&gt; object or wrapper contains details and features of the underlying the database.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cover Photo by &lt;a href="https://unsplash.com/@ninjason&amp;gt;Jason%20Leung&amp;lt;/a&amp;gt;%20on%20&amp;lt;a%20href="&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The post first appeared in &lt;a href="https://kracekumar.com/post/django_model_fields_orm_part2/"&gt;my blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>database</category>
    </item>
    <item>
      <title>Structure - Django ORM Working - Part 1</title>
      <dc:creator>Kracekumar</dc:creator>
      <pubDate>Sun, 27 Jun 2021 07:39:59 +0000</pubDate>
      <link>https://dev.to/kracekumar/structure-django-orm-working-part-1-10ch</link>
      <guid>https://dev.to/kracekumar/structure-django-orm-working-part-1-10ch</guid>
      <description>&lt;p&gt;Django ORM hides a lot of complexity while developing the web application. The data model declaration and querying pattern are simplified, whereas it's structured differently behind the scenes. The series of blog posts will explain Django ORM working(not just converting Python code to SQL), model declaration, querying (manager, queryset), supporting multiple drivers, writing custom queries, migrations etc...&lt;/p&gt;

&lt;p&gt;Consider a model definition from the &lt;a href="https://docs.djangoproject.com/en/3.2/intro/tutorial02/"&gt;Django tutorial&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;question_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pub_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'date published'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;choice_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;votes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Question and Choice model class derives from &lt;code&gt;models.Model&lt;/code&gt;. Inheriting &lt;code&gt;Model&lt;/code&gt; signals Django at run-time the class is a database model. &lt;code&gt;Question&lt;/code&gt; model(later converted to a table) contains two extra class variables, &lt;code&gt;question_text&lt;/code&gt; and &lt;code&gt;pub_date&lt;/code&gt;, which will be two columns in the table. Their type is indicated by creating an instance of the respective type of fields, here &lt;code&gt;models.CharField, models.DateTimeField&lt;/code&gt;. A similar work applies to the Choice model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Querying
&lt;/h3&gt;

&lt;p&gt;Let's display all the instances of &lt;code&gt;Question&lt;/code&gt; (all the rows in the table - polls_question).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuerySet&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, the table is empty, and the method call returns empty result. The two things to notice are &lt;code&gt;objects.all()&lt;/code&gt; and &lt;code&gt;QuerySet&lt;/code&gt;. All the data entry in and out of the database through Django ORM happens through the object's interface. All the results are wrapped inside the QuerySet, even empty ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  From where does the &lt;code&gt;objects&lt;/code&gt; instance come?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, &amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, &amp;lt;class '&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.python.org/3.8/library/stdtypes.html#class.mro"&gt;Every Python class has a Method Resolution Order, which determines the behavior of the class/method invocation&lt;/a&gt;. In the above example, the Bar class inherits the Foo class. The &lt;code&gt;mro&lt;/code&gt; method returns the order from child to patent class, Bar inherits Foo, Foo inherits object. As you can see, the Foo class has no inherited class in the code, but the &lt;code&gt;mro&lt;/code&gt; method says Foo inherits object. All the Python class inherits from the object; hence &lt;code&gt;mro&lt;/code&gt; method returns &lt;code&gt;object&lt;/code&gt; as the last parent in the list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;polls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, 
&amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, 
&amp;lt;class '&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MRO for &lt;code&gt;Question&lt;/code&gt; is clear and returns result as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Bar&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Question
&amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;polls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Question.objects
&amp;lt;django.db.models.manager.Manager object at 0x10bd7f1c0&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Question.objects.mro()
Traceback (most recent call last):
  File "&amp;lt;console&amp;gt;", line 1, in &amp;lt;module&amp;gt;
AttributeError: '&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="s"&gt;' object has no attribute '&lt;/span&gt;&lt;span class="n"&gt;mro&lt;/span&gt;&lt;span class="s"&gt;'
&amp;gt;&amp;gt;&amp;gt; Question.objects.__class__.mro()
[&amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, &amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseManagerFromQuerySet&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, &amp;lt;class '&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseManager&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;, &amp;lt;class '&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.python.org/3/reference/datamodel.html#object.__repr__"&gt;representation&lt;/a&gt; of &lt;code&gt;Question.objects&lt;/code&gt; is different from the representation of &lt;code&gt;Bar&lt;/code&gt; and &lt;code&gt;Question&lt;/code&gt; classes. As the name indicates, &lt;code&gt;objects&lt;/code&gt; is an instance of the &lt;code&gt;Manager&lt;/code&gt;. The &lt;code&gt;objects&lt;/code&gt;, the instance of Manager class, inherits &lt;code&gt;BaseManagerFromQuerySet&lt;/code&gt; and &lt;code&gt;BaseManager&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Choice&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;polls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Choice&lt;/span&gt;&lt;span class="s"&gt;'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Choice.objects
&amp;lt;django.db.models.manager.Manager object at 0x10bd7f0a0&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Question.objects
&amp;lt;django.db.models.manager.Manager object at 0x10bd7f1c0&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Choice.objects is Question.objects
False
&amp;gt;&amp;gt;&amp;gt; Choice.objects == Question.objects
True
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What? Even though the instance uses different id but equality test returns &lt;code&gt;True&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# It's decalared in manager class
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__eq__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__class__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_constructor_args&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_constructor_args&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic for checking the equality has two pieces - both operands should be of the same type and their constructor args are same. In this case(behind the scenes), both the managers were called with empty arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_constructor_args&lt;/span&gt;
&lt;span class="p"&gt;((),&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_constructor_args&lt;/span&gt;
&lt;span class="p"&gt;((),&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next post, I'll cover how &lt;code&gt;models.*Field&lt;/code&gt; works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The Django model inherits &lt;code&gt;model.Model&lt;/code&gt; and all the class variables initialized with &lt;code&gt;model.*Field&lt;/code&gt; automatically behaves like a column in the table.&lt;/li&gt;
&lt;li&gt;The interactions to the database happen through &lt;code&gt;ModelManager&lt;/code&gt; via &lt;code&gt;objects&lt;/code&gt; attribute.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Notes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This post initially appeared in &lt;a href="https://kracekumar.com/post/structure_django_orm_working_part1/"&gt;my blog&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Cover Photo by &lt;a href="https://unsplash.com/@derekrliang&amp;gt;Derek%20Liang&amp;lt;/a&amp;gt;%20on%20&amp;lt;a%20href="&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>database</category>
    </item>
  </channel>
</rss>
