Django overview and debugging




1: Django project structure


Now that you've setup a basic Django project let's go over some of the files and folders you will be using that are already created upon installation.  We do not cover every single file, instead we will focus on the ones we actually use throughout this course.  Don't worry about memorizing all of the definitions.  This section is intended as a brief overview before you get deeper into the development cycle.

 

Django's folder structure

env > mysite

env > mysite folderGIF

So far, you have seen that the virtual environment env contains the Django project mysite. All of the folders and files we use in this tutorial will be within this mysite folder. Within this folder are main, the folder where we add most of our web app's functionality, and mysite, the folder containing the project's configuration settings.

 

Files and folders in the main folder

env > mysite > main

mysite > main folderGIF

If you recall, the main folder was made when we ran the command py manage.py startapp main. This folder contains related files for rendering web pages and connecting to our database . In the main folder we have:

 

env > mysite > main > migrations > 0001_initial.py

# Generated by Django 2.1.15 on 2020-04-13 21:37

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Example',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('example_name', models.CharField(max_length=150)),
            ],
        ),
    ]

migrations - files will be automatically added to this folder as we update our project database, db.sqlite3.  Each migration file added contains information on how the database will be changed/updated.  See example above.

 

env > mysite > main > templates > main > home.html

<p>Hello world!</p>

templates - folder containing HTML documents for the project, such as home.html

 

env > mysite > main > admin.py

from django.contrib import admin
from .models import Product

# Register your models here.

admin.site.register(Product)

admin.py - Django comes with a pre-made admin page if you visit http://127.0.0.1:8000/admin/.  This file is used to specify what should get added to the admin page since it starts off blank. We'll eventually create a login and interact with the admin page to add products and articles to our site.

Django admin

 

env > mysite > main > apps.py

from django.apps import AppConfig


class MainConfig(AppConfig):
    name = 'main'

apps.py - lists the name of the app we created, in this case "main".  We actually added this file to mysite > settings.py under INSTALLED_APPS in the previous lesson.

 

env > mysite > main > models.py

from django.db import models

# Create your models here.
class Product(models.Model):
	product_name = models.CharField(max_length=150)

models.py - lists all of the model classes we create.  Remember how we made a class in the Python section of this course?  Similarly, we will add special Django classes called model classes that store information we need for our users.  Once written, we can also add these classes to the admin page in order to create and edit instances of the class.  For example, we will create a Product class that will hold information for different products including a field for product names.  Next, we register the Product class in admin.py so we can actually create and edit different products in the Django admin page.  You'll have plenty of opportunity to understand this concept.

 

env > mysite > main > tests.py

from django.test import TestCase

# Create your tests here.

tests.py - we won't be creating any tests, but this file is used to write a Python script that can test your web app's functionality.

 

env > mysite > main > urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
]

urls.py - when you click on a link in your web app, the link will connect to a specific "path" to display the correct information.  For example, if you click on a login button, you will be brought to the login page.  The urls.py file contains the paths for our "main" app and allows us to route where a user goes when they click a link.  

 

env > mysite > main > views.py

from django.shortcuts import render

# Create your views here.
def homepage(request):
	return render(request = request, template_name="main/home.html"	)

views.py - when a user clicks a link or reloads a page, their request is handled by urls.py, which links to a function in views.py.  As demonstrated with the homepage, a path in urls.py connects to a homepage function located in views.py.  This function is responsible for rendering the HTML template in the browser.  Functions that render web pages belong in views.py.

 

Files in the mysite folder

env > mysite > mysite

mysite > mysite folderGIF

The mysite folder is the configuration folder, or the folder with the Django project's settings. In the mysite folder we have:

 

env > mysite > mysite > settings.py

"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 2.1.15.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""

import os


# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '*************************************'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

...

settings.py - contains all basic configuration settings and used to lists all installed packages.  We will continue to edit settings.py with different parameters as we install other packages.

 

env > mysite > mysite > urls.py

"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include ('main.urls')),
]

urls.py - similar to the urls.py file in our main folder, except this file routes urls for our entire project.  You'll notice we have a path for the admin site as well as a path to connect to the other urls.py file.

 

env > mysite > mysite > wsgi.py

"""
WSGI config for mysite project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')

application = get_wsgi_application()

wsgi.py - specifically used in Python web applications, this file allows your web app to connect you your development server or in future cases, production server.

 

env > mysite > db.sqlite3

5351 4c69 7465 2066 6f72 6d61 7420 3300
1000 0101 0040 2020 0000 006a 0000 0035
0000 0022 0000 0001 0000 0060 0000 0004
0000 0000 0000 0000 0000 0001 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 006a
...

db.sqlite3 - the database we use for our project.  The database is actually located in the first mysite folder and does not exist until applying migrations in the CLI.  When you enter information in the admin page, the actual text is saved in the database.  Once created, if you click on the database file, you'll notice information is stored in columns.  This allows the data to be stored more efficiently.  








2: Django debugging


Errors occur when learning to code and even experienced coders encounter unforeseen bugs.  Luckily, for our purposes, Django handles error reporting by displaying a yellow web page when a problem occurs.  An example of this page is listed below:

 

Django debug example

Django debug page

First read the error at the top of the page. Start to hypothesize why this might have occurred.  In this case, we see "NameError at /" and "name 'render' is not defined".  We can already identify the error has something to do with a line of code that has 'render' in it.  The next list of details include all the information you need to identify the issue.

 

What is the Request Method?

Usually request methods are GET or POST.  The former signifies that a user sent a request intended to receive information, such as when you load the homepage of website and information is being sent to your computer screen.  The latter is used to send information to a server, such as when you enter credentials to sign-in to a website or submit a comment in a forum. 

 

What is the Request URL?

The URL that caused the error. In this case, loading the homepage created the error.

 

What is the Exception Type?

There are a variety of exception types.  Two notable types are NameError and TypeError.  NameError means a specific name in your code is not defined while TypeError signifies you tried to perform an operation on the wrong type of variable (i.e. you tried to divide a string with an integer).  This same error happened back in the Python exercises.

 

What is the Exception Value?

The exact reason for the error.  The example above states "name 'render' is not defined" meaning "render" is not a built-in Python feature and must be either defined in your code or imported from a file that does define it.

 

What is the Exception Location?

The exact file and line that caused the error.  The error above is occurring in the views.py, line 12.

 

What is the Traceback?

Django debug page traceback

The files and lines of code that were ran until the error occurred.  Here you can see the exact line causing the problem.  In this case, the render function is called but never defined since we forgot to import it at the top of the file.  

 

What happens if you still need help?

If you are confused about how to solve your problem, click the red bug button in the top-right to a see brief list of possible errors and solutions.

If you think your mistake is something pretty common, copy + paste your error into Google and find a Stack Overflow answer to solve the issue.  Lastly, if you are still confused, send us a message with the green tech support button.  We are available 10 AM - 5 PM PST and willing to assist with any issues related to this tutorial.  

Many people find themselves frustrated with errors and bugs.  However, paying attention to the exception type and traceback will build experience and decrease time spent debugging.  Remember not to get discouraged since debugging is an integral part of web development and will become less difficult with time. 






Quiz Questions


1. What is the purpose of views.py?


2. Which folder holds HTML files in Django?  Choose the most specific answer available.


3. What is a traceback?


Next lesson


Check out the comments and debug buttons if you get stuck.