A starter app.py file in Django might have the following sections:

  1. Imports
  2. Admin registration
  3. View functions
  4. URL patterns
  5. WSGI handler

And a few other items. Idiomatically, Django will have a much more clear separation of concerns.

Admin site

In a file called blogs/admin.py we will generally handle all the model registration:

from django.contrib import admin
from .models import Blog, BlogPost
 
admin.site.register((Blog, BlogPost))

View functions

In general, view functions should be placed in their own file within their respective app directories. Here, we have blogs/views.py:

from django.shortcuts import render
 
from .models import Blog, BlogPost
 
 
def index(request):
    return render(request, "index.html")
 
def blogs(request):
    all_blogs = Blog.objects.all()
    context = {"blogs": all_blogs}
    return render(request, "blogs.html", context)
 
def blog(request, blog_id):
    blog = Blog.objects.get(id=blog_id)
    posts = blog.blogpost_set.all()
    
    context = {
        "blog": blog,
        "posts": posts,
    }
    return render(request, "blog.html", context)
 
def post(request, post_id):
    post = BlogPost.objects.get(id=post_id)
    blog = post.blog
 
    context = {
        "post" : post,
        "blog" : blog
    }
 
    return render(request, "post.html", context)

this means that the app.py file only contains relative imports, URL patterns, and the WSGI handler:

from django.urls import path, include
from django.core.handlers.wsgi import WSGIHandler
from django.contrib import admin
 
urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("blogs.urls"))
]
 
 
application = WSGIHandler()

Note the use of include so make sure that the URL patterns include the ones we have banished to urls.py.

This change means that there is nothing specific to the blogs app in the main application file. It, therefore, does only two things:

  1. Define which URLs are used in the overall project
  2. Designate a WSGI handler for the server

Templates

Like everything else, templates associated with a specific app should be placed within the directory of that app. For example, the blogs app should have the following structure:

blogs
├── admin.py
├── migrations
│   ├── ...
├── models.py
├── templates
│   └── blogs
│       ├── base.html
│       ├── blog.html
│       ├── blogs.html
│       ├── index.html
│       └── post.html
├── urls.py
└── views.py

Note that due to Django’s template discovery mechanism the blog templates are stored in blogs/templates/blogs.