{"id":1686,"date":"2026-09-16T05:59:07","date_gmt":"2026-09-16T05:59:07","guid":{"rendered":"https:\/\/nayananimsara.online\/?p=1686"},"modified":"2026-09-16T06:00:03","modified_gmt":"2026-09-16T06:00:03","slug":"django-app-structure-explained","status":"publish","type":"post","link":"https:\/\/nayananimsara.online\/django-app-structure-explained\/","title":{"rendered":"Django App Structure Explained: 7 Files You&#8217;ll Actually Use"},"content":{"rendered":"\n<h1 id=\"django-app-structure-explained-7-files-youll-actually-use\" class=\"wp-block-heading\">Django App Structure Explained: 7 Files You&#8217;ll Actually Use<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The first app I ever created in Django was called <code>blog<\/code>. I remember running <code>python manage.py startapp blog<\/code>, watching a new folder pop up, and thinking \u2014 okay, now what? I had just gone through the pain of understanding the project structure, and now here was a whole new set of files sitting inside this smaller folder, waiting to confuse me all over again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So let&#8217;s go through it properly this time. If you&#8217;ve already read my post on the Django project structure, this one picks up right where that left off \u2014 the moment you create your first app inside that project.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#django-app-structure-explained-7-files-youll-actually-use\">Django App Structure Explained: 7 Files You&#8217;ll Actually Use<\/a><ul><li><a href=\"#project-vs-app-a-quick-reminder\">Project vs. App \u2014 A Quick Reminder<\/a><\/li><li><a href=\"#django-app-structure-explained-the-command-that-creates-an-app\">Django App Structure Explained The Command That Creates an App<\/a><\/li><li><a href=\"#1-models-py-where-your-data-lives\">1. models.py \u2014 Where Your Data Lives<\/a><\/li><li><a href=\"#2-views-py-the-logic-behind-every-page\">2. views.py \u2014 The Logic Behind Every Page<\/a><\/li><li><a href=\"#3-admin-py-your-free-dashboard\">3. admin.py \u2014 Your Free Dashboard<\/a><\/li><li><a href=\"#4-apps-py-quiet-configuration\">4. apps.py \u2014 Quiet Configuration<\/a><\/li><li><a href=\"#5-tests-py-a-placeholder-for-good-habits\">5. tests.py \u2014 A Placeholder for Good Habits<\/a><\/li><li><a href=\"#6-migrations-tracking-every-change\">6. migrations\/ \u2014 Tracking Every Change<\/a><\/li><li><a href=\"#7-init-py-same-job-different-folder\">7. init.py \u2014 Same Job, Different Folder<\/a><\/li><li><a href=\"#the-step-everyone-forgets\">The Step Everyone Forgets<\/a><\/li><li><a href=\"#how-project-and-app-files-work-together\">How Project and App Files Work Together<\/a><\/li><li><a href=\"#final-thoughts\">Final Thoughts<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 id=\"project-vs-app-a-quick-reminder\" class=\"wp-block-heading\">Project vs. App \u2014 A Quick Reminder<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before diving into the files, it&#8217;s worth repeating this distinction because it trips people up constantly: a <strong>project<\/strong> is the whole website. An <strong>app<\/strong> is one feature of it \u2014 a blog, a store, a comments system, whatever. One project can hold many apps. That&#8217;s the whole design philosophy behind Django, and it&#8217;s why the folder you&#8217;re about to explore looks so different from the project folder.<\/p>\n\n\n\n<h2 id=\"django-app-structure-explained-the-command-that-creates-an-app\" class=\"wp-block-heading\">Django App Structure Explained The Command That Creates an App<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>python manage.py startapp blog<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run this from inside your project&#8217;s root folder \u2014 the same level as <code>manage.py<\/code>. Django creates a new folder named <code>blog<\/code>, sitting right next to <code>manage.py<\/code>, not inside your settings package. That trips up a lot of beginners who expect it to nest inside the inner project folder. It doesn&#8217;t.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what you&#8217;ll find inside:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>blog\/\n    migrations\/\n        __init__.py\n    __init__.py\n    admin.py\n    apps.py\n    models.py\n    tests.py\n    views.py<\/code><\/pre>\n\n\n\n<h2 id=\"1-models-py-where-your-data-lives\" class=\"wp-block-heading\">1. models.py \u2014 Where Your Data Lives<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the file I open first, every single time. <code>models.py<\/code> is where you define your database tables using plain Python classes. If I&#8217;m building a blog, my <code>Post<\/code> model might look like this:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from django.db import models\n\nclass Post(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    created_at = models.DateTimeField(auto_now_add=True)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Django takes this Python class and translates it into an actual database table behind the scenes. You never have to write raw SQL for basic operations \u2014 that&#8217;s one of the things that hooked me on Django early on.<\/p>\n\n\n\n<h2 id=\"2-views-py-the-logic-behind-every-page\" class=\"wp-block-heading\">2. views.py \u2014 The Logic Behind Every Page<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you have data, you need something to decide what gets shown to a visitor. That&#8217;s <code>views.py<\/code>. A simple view might just fetch all blog posts and pass them to a template:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from django.shortcuts import render\nfrom .models import Post\n\ndef post_list(request):\n    posts = Post.objects.all()\n    return render(request, 'blog\/post_list.html', {'posts': posts})<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Every page on your site that shows dynamic content is going to route through a view like this eventually.<\/p>\n\n\n\n<h2 id=\"3-admin-py-your-free-dashboard\" class=\"wp-block-heading\">3. admin.py \u2014 Your Free Dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This file genuinely surprised me the first time I understood it. By registering a model here:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from django.contrib import admin\nfrom .models import Post\n\nadmin.site.register(Post)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You instantly get a full admin interface at <code>\/admin\/<\/code> where you can add, edit, and delete blog posts through a browser \u2014 no extra code required. I still think this is one of Django&#8217;s most underrated features for beginners.<\/p>\n\n\n\n<h2 id=\"4-apps-py-quiet-configuration\" class=\"wp-block-heading\">4. apps.py \u2014 Quiet Configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This file defines a small config class for the app itself. Django uses it internally to identify and load the app correctly. You&#8217;ll rarely need to edit it, but it&#8217;s good to know it exists and roughly why.<\/p>\n\n\n\n<h2 id=\"5-tests-py-a-placeholder-for-good-habits\" class=\"wp-block-heading\">5. tests.py \u2014 A Placeholder for Good Habits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Django creates this file empty on purpose, almost like a nudge. It&#8217;s where you&#8217;ll eventually write tests to check that your models and views behave correctly. I ignored this file for my first few projects \u2014 I don&#8217;t recommend doing the same once your projects grow past the beginner stage.<\/p>\n\n\n\n<h2 id=\"6-migrations-tracking-every-change\" class=\"wp-block-heading\">6. migrations\/ \u2014 Tracking Every Change<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every time you add or change a field in <code>models.py<\/code> and run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>python manage.py makemigrations<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Django creates a new file inside this folder describing exactly what changed. Then <code>python manage.py migrate<\/code> applies those changes to your actual database. I think of this folder as a changelog for your database structure \u2014 it&#8217;s incredibly useful once you&#8217;re working with a team or deploying updates.<\/p>\n\n\n\n<h2 id=\"7-init-py-same-job-different-folder\" class=\"wp-block-heading\">7. <strong>init<\/strong>.py \u2014 Same Job, Different Folder<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Just like in the project folder, this file is empty and simply tells Python to treat <code>blog<\/code> as a package. Nothing to configure here.<\/p>\n\n\n\n<h2 id=\"the-step-everyone-forgets\" class=\"wp-block-heading\">The Step Everyone Forgets<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Creating the app with <code>startapp<\/code> does not automatically activate it. You still need to open <code>settings.py<\/code> and add it to <code>INSTALLED_APPS<\/code>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSTALLED_APPS = &#91;\n    ...\n    'blog',\n]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve lost count of how many times a student has messaged me confused about why their model isn&#8217;t showing up in migrations, only to realize this one line was missing.<\/p>\n\n\n\n<h2 id=\"how-project-and-app-files-work-together\" class=\"wp-block-heading\">How Project and App Files Work Together<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once your app is registered, everything connects: <code>urls.py<\/code> in your project routes requests to views in your app, those views pull data through <code>models.py<\/code>, and <code>admin.py<\/code> gives you a way to manage that data without writing a single form by hand. It&#8217;s a small, tidy loop once you see it laid out this way.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you haven&#8217;t gone through it yet, my earlier post on the Django project structure covers the outer layer this app now plugs into. And for anything deeper on apps specifically, the <a href=\"https:\/\/docs.djangoproject.com\/en\/stable\/ref\/applications\/\" target=\"_blank\" rel=\"noopener\">official Django documentation<\/a> is worth a read.<\/p>\n\n\n\n<h2 id=\"final-thoughts\" class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A Django app might look like just another folder of unfamiliar files at first, but each one has a clear, narrow job. <code>models.py<\/code> defines your data, <code>views.py<\/code> decides what&#8217;s shown, <code>admin.py<\/code> gives you a dashboard for free, and <code>migrations\/<\/code> quietly tracks it all over time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go create a throwaway app right now, add one simple model, and register it in the admin panel. Seeing it work end to end is what finally made this click for me.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/nayananimsara.online\/course\/django-for-beginners-learn-python-web-development-from-scratch\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/nayananimsara.online\/course\/django-for-beginners-learn-python-web-development-from-scratch\/\" rel=\"noreferrer noopener\">Full Course<\/a><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"tg-oembed-container\"><iframe title=\"WebHD 720p 5\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/HE2olbf-jgI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Django App Structure Explained: 7 Files You&#8217;ll Actually Use The first app I ever created in Django was called blog. I remember running python manage.py startapp blog, watching a new folder pop up, and thinking \u2014 okay, now what? I had just gone through the pain of understanding the project structure, and now here was [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1690,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"elearning_container_layout":"tg-site-layout--default","elearning_sidebar_layout":"tg-site-layout--default","elearning_remove_content_margin":false,"elearning_sidebar":"default","elearning_transparent_header":"customizer","elearning_logo":0,"elearning_header_style":"default","elearning_menu_item_color":"","elearning_menu_item_hover_color":"","elearning_menu_item_active_color":"","elearning_menu_item_active_style":"","elearning_page_header":true,"footnotes":""},"categories":[64],"tags":[],"class_list":["post-1686","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-django"],"_links":{"self":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1686","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/comments?post=1686"}],"version-history":[{"count":4,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1686\/revisions"}],"predecessor-version":[{"id":1692,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/posts\/1686\/revisions\/1692"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/media\/1690"}],"wp:attachment":[{"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/media?parent=1686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/categories?post=1686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nayananimsara.online\/wp-json\/wp\/v2\/tags?post=1686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}