{"id":5950,"date":"2022-11-30T07:12:19","date_gmt":"2022-11-30T07:12:19","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=5950"},"modified":"2022-12-24T02:34:02","modified_gmt":"2022-12-24T02:34:02","slug":"django-todo-app","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/django-tutorial\/django-todo-app\/","title":{"rendered":"Django Todo App"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to create a Django Todo App project including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a virtual environment<\/li>\n\n\n\n<li>Install the Django package<\/li>\n\n\n\n<li>Create a new project<\/li>\n\n\n\n<li>Adding static files<\/li>\n\n\n\n<li>Setting up templates<\/li>\n\n\n\n<li>Create the todo app<\/li>\n\n\n\n<li>Create the Task model and apply migrations<\/li>\n<\/ul>\n\n\n\n<p class=\"note\">You can download the final code for this <a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/todo_list_1.zip\">Django Todo App<\/a> here.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='creating-a-virtual-environment'>Creating a virtual environment <a href=\"#creating-a-virtual-environment\" class=\"anchor\" id=\"creating-a-virtual-environment\" title=\"Anchor for Creating a virtual environment\">#<\/a><\/h2>\n\n\n\n<p>Run the following python command to <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-virtual-environments\/\">create a virtual environment<\/a> using the built-in <code>venv<\/code> module:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python -m venv venv<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And activate the <code>venv<\/code> virtual environment using the following command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">venv\\scripts\\activate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you use macOS and Linux, you can use the following <code>python3<\/code> command to create a new virtual environment:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">python3 -m venv venv<\/code><\/span><\/pre>\n\n\n<p>And activate it using the following command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">source venv\/bin\/activate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='install-the-django-package'>Install the Django package <a href=\"#install-the-django-package\" class=\"anchor\" id=\"install-the-django-package\" title=\"Anchor for Install the Django package\">#<\/a><\/h2>\n\n\n\n<p>Since Django is a third-party package, you need to install it using the following <code>pip<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">pip install django<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='creating-a-new-project'>Creating a new project <a href=\"#creating-a-new-project\" class=\"anchor\" id=\"creating-a-new-project\" title=\"Anchor for Creating a new project\">#<\/a><\/h2>\n\n\n\n<p>To create a new project <code>todo_list<\/code>, you use the <code>startproject<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">django-admin startproject todo_list<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='adding-static-files'>Adding static files <a href=\"#adding-static-files\" class=\"anchor\" id=\"adding-static-files\" title=\"Anchor for Adding static files\">#<\/a><\/h2>\n\n\n\n<p>First, create a <code>static<\/code> directory inside the project directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">mkdir <span class=\"hljs-keyword\">static<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, set the <code>STATICFILES_DIRS<\/code> to the <code>static<\/code> directory in the <code>settings.py<\/code> after the <code>STATIC_URL<\/code> file so that Django can find the static files in the <code>static<\/code> directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span>STATIC_URL = <span class=\"hljs-string\">'static\/'<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>STATICFILES_DIRS = &#91;BASE_DIR \/ <span class=\"hljs-string\">'static'<\/span>]\n<\/span><\/mark><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, create three directories <code>js<\/code>, <code>css<\/code>, and <code>images<\/code> inside the <code>static<\/code> directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cd <span class=\"hljs-keyword\">static<\/span>\nmkdir css images js<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>static<\/code> directory will look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">\u251c\u2500\u2500 static\n|  \u251c\u2500\u2500 css\n|  \u251c\u2500\u2500 images\n|  \u2514\u2500\u2500 js<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, copy the <code>style.css<\/code> file and <code>feature.jpg<\/code> image from the download file to the <code>css<\/code> and <code>images<\/code> directories.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='setting-up-templates'>Setting up templates <a href=\"#setting-up-templates\" class=\"anchor\" id=\"setting-up-templates\" title=\"Anchor for Setting up templates\">#<\/a><\/h2>\n\n\n\n<p>First, create a <code>templates<\/code> directory inside the project directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">mkdir templates<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, create a <code>base.html<\/code> template inside the <code>templates<\/code> directory with the following contents:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">{%load static %}\n<span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charset<\/span>=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"{% static 'css\/style.css' %}\"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Todo List<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"header\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">footer<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"footer\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><span class=\"hljs-symbol\">&amp;copy;<\/span> Copyright {% now \"Y\" %} by <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"https:\/\/www.pythontutorial.net\"<\/span>&gt;<\/span>Python Tutorial<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">footer<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>base.html<\/code> template uses the <code>style.css<\/code> file from the <code>static\/css<\/code> directory.<\/p>\n\n\n\n<p>Third, configure the template directory in the <code>TEMPLATES<\/code> of the <code>settings.py<\/code> file so that Django can find the <code>base.html<\/code> template.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span>TEMPLATES = &#91;\n<\/span><\/span><span class='shcb-loc'><span>    {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">'BACKEND'<\/span>: <span class=\"hljs-string\">'django.template.backends.django.DjangoTemplates'<\/span>,\n<\/span><\/span><mark class='shcb-loc'><span>        <span class=\"hljs-string\">'DIRS'<\/span>: &#91;BASE_DIR \/ <span class=\"hljs-string\">'templates'<\/span> ],\n<\/span><\/mark><span class='shcb-loc'><span>        <span class=\"hljs-string\">'APP_DIRS'<\/span>: <span class=\"hljs-literal\">True<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">'OPTIONS'<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-string\">'context_processors'<\/span>: &#91;\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-string\">'django.template.context_processors.debug'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-string\">'django.template.context_processors.request'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-string\">'django.contrib.auth.context_processors.auth'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-string\">'django.contrib.messages.context_processors.messages'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>            ],\n<\/span><\/span><span class='shcb-loc'><span>        },\n<\/span><\/span><span class='shcb-loc'><span>    },\n<\/span><\/span><span class='shcb-loc'><span>]\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fourth, create the <code>home.html<\/code> template inside the <code>templates<\/code> directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">{%extends <span class=\"hljs-string\">'base.html'<\/span>%}\n{%load <span class=\"hljs-keyword\">static<\/span> %}\n{%block content%}\n\t&lt;section <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span><\/span>=<span class=\"hljs-string\">\"feature\"<\/span>&gt;\n\t\t<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"feature-content\"<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Todo<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Todo helps you more focus, either work or play.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\t\n\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-primary cta\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"#\"<\/span>&gt;<\/span>Get Started<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\t\t<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"{%static 'images\/feature.jpg'%}\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"feature-image\"<\/span>&gt;<\/span>\n\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span><\/span>\n{%endblock content%}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='creating-a-todo-application'>Creating a todo application <a href=\"#creating-a-todo-application\" class=\"anchor\" id=\"creating-a-todo-application\" title=\"Anchor for Creating a todo application\">#<\/a><\/h2>\n\n\n\n<p>First, create a <code>todo<\/code> app in the <code>todo_list<\/code> project using the <code>startapp<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">django-admin startapp todo<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, register the <code>todo<\/code> app in the <code>settings.py<\/code> of the <code>todo_list<\/code> project by adding it to the <code>INSTALLED_APPS<\/code> list:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span>INSTALLED_APPS = &#91;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.admin'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.auth'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.contenttypes'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.sessions'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.messages'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">'django.contrib.staticfiles'<\/span>,\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-string\">'todo'<\/span>,\n<\/span><\/mark><span class='shcb-loc'><span>]\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, create the <code>templates<\/code> directory inside the <code>todo<\/code> app directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">cd todo\nmkdir templates<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fourth, create the <code>todo<\/code> directory inside the <code>templates<\/code> directory. The directory name must be the same as the app name.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">cd templates\nmkdir todo<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fifth, define a <code>home()<\/code> view function inside the <code>views.py<\/code> of the todo app that renders the <code>home.html<\/code> template:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.shortcuts <span class=\"hljs-keyword\">import<\/span> render\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">home<\/span><span class=\"hljs-params\">(request)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">return<\/span> render(request,<span class=\"hljs-string\">'home.html'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Sixth, create <code>urls.py<\/code> file in the <code>todo<\/code> app and define a route that maps to the home URL with the <code>home()<\/code>  view function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.urls <span class=\"hljs-keyword\">import<\/span> path\n<span class=\"hljs-keyword\">from<\/span> . <span class=\"hljs-keyword\">import<\/span> views\n\nurlpatterns = &#91;\n    path(<span class=\"hljs-string\">''<\/span>, views.home, name=<span class=\"hljs-string\">'home'<\/span>),\n]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Seventh, include the <code><code>urls.py<\/code><\/code> of the <code>todo<\/code> app in the <code><code>urls.py<\/code><\/code> of the project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n<\/span><\/span><mark class='shcb-loc'><span><span class=\"hljs-keyword\">from<\/span> django.urls <span class=\"hljs-keyword\">import<\/span> path, include\n<\/span><\/mark><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>urlpatterns = &#91;\n<\/span><\/span><span class='shcb-loc'><span>    path(<span class=\"hljs-string\">'admin\/'<\/span>, admin.site.urls),\n<\/span><\/span><mark class='shcb-loc'><span>    path(<span class=\"hljs-string\">''<\/span>,include(<span class=\"hljs-string\">'todo.urls'<\/span>))\n<\/span><\/mark><span class='shcb-loc'><span>]\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Eighth, run the Django development server from the <code>todo_list<\/code> directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python manage.py runserver<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, open <code>http:\/\/127.0.0.1:8000\/<\/code> on a web browser, you&#8217;ll see the blog page that shows the homepage:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"652\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-1024x652.png\" alt=\"\" class=\"wp-image-5952\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-1024x652.png 1024w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-300x191.png 300w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-768x489.png 768w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list.png 1392w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id='create-the-task-model'>Create the Task model <a href=\"#create-the-task-model\" class=\"anchor\" id=\"create-the-task-model\" title=\"Anchor for Create the Task model\">#<\/a><\/h2>\n\n\n\n<p>First, define the <code>Task<\/code> model in the <code>models.py<\/code> of the <code>todo<\/code> app:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.db <span class=\"hljs-keyword\">import<\/span> models\n<span class=\"hljs-keyword\">from<\/span> django.contrib.auth.models <span class=\"hljs-keyword\">import<\/span> User\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Task<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n    title = models.CharField(max_length=<span class=\"hljs-number\">255<\/span>)\n    description = models.TextField(null=<span class=\"hljs-literal\">True<\/span>, blank=<span class=\"hljs-literal\">True<\/span>)\n    completed = models.BooleanField(default=<span class=\"hljs-literal\">False<\/span>)\n    created_at = models.DateTimeField(auto_now_add=<span class=\"hljs-literal\">True<\/span>)\n    user = models.ForeignKey(User,on_delete=models.CASCADE, null=<span class=\"hljs-literal\">True<\/span>, blank=<span class=\"hljs-literal\">True<\/span>)\n    \n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> self.title\n    \n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Meta<\/span>:<\/span>\n        ordering = &#91;<span class=\"hljs-string\">'completed'<\/span>]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, register the <code>Task<\/code> model in the <code>admin.py<\/code> of the <code>todo<\/code> app so that you can manage it on the admin page:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> Task\n\nadmin.site.register(Task)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, make migrations by running the <code>makemigrations<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python manage.py makemigrations<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Migrations for 'todo':\n  todo\\migrations\\0001_initial.py\n    - Create model Task<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fourth, apply the migrations to the database:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python manage.py migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Operations to perform:\n  Apply all migrations: admin, auth, contenttypes, sessions, todo\nRunning migrations:\n  Applying contenttypes.0001_initial... OK\n  Applying auth.0001_initial... OK\n  Applying admin.0001_initial... OK\n  Applying admin.0002_logentry_remove_auto_add... OK\n  Applying admin.0003_logentry_add_action_flag_choices... OK\n  Applying contenttypes.0002_remove_content_type_name... OK\n  Applying auth.0002_alter_permission_name_max_length... OK\n  Applying auth.0003_alter_user_email_max_length... OK\n  Applying auth.0004_alter_user_username_opts... OK\n  Applying auth.0005_alter_user_last_login_null... OK\n  Applying auth.0006_require_contenttypes_0002... OK\n  Applying auth.0007_alter_validators_add_error_messages... OK\n  Applying auth.0008_alter_user_username_max_length... OK\n  Applying auth.0009_alter_user_last_name_max_length... OK\n  Applying auth.0010_alter_group_name_max_length... OK\n  Applying auth.0011_update_proxy_permissions... OK\n  Applying auth.0012_alter_user_first_name_max_length... OK\n  Applying sessions.0001_initial... OK\n  Applying todo.0001_initial... OK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fifth, create a superuser by executing the <code>createsuperuser<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python manage.py createsuperuser<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Username: john\nEmail address:\nPassword:\nPassword (again):\nSuperuser created successfully.<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Sixth, restart the Django development server:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python manage.py runserver<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Seven, log in to the admin page and create three tasks:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"248\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-task-list.png\" alt=\"django todo list - task list\" class=\"wp-image-5963\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-task-list.png 562w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/11\/django-todo-list-task-list-300x132.png 300w\" sizes=\"auto, (max-width: 562px) 100vw, 562px\" \/><\/figure>\n\n\n\n<p class=\"note\">You can download the final code for this <a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/todo_list_1.zip\">Django Todo App<\/a> here.<\/p>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"5950\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-todo-app\/\"\n\t\t\t\tdata-post-title=\"Django Todo App\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"5950\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-todo-app\/\"\n\t\t\t\tdata-post-title=\"Django Todo App\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial helps you get started with the Django Todo App project by setting up the project structure.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":5531,"menu_order":12,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5950","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5950","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=5950"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5950\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5531"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=5950"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}