openskills.info
Django Fundamentals logo

Django Fundamentals

itWeb development

Django Fundamentals

Django is a Python framework for building database-backed web applications. It brings URL routing, request handling, database access, HTML templates, forms, authentication, an administrative site, testing, and security controls into one system.

That breadth is Django's main proposition. You follow its project structure and conventions. In return, you avoid assembling a separate library for every common server-side task.

Django fits applications whose server owns business rules and persistent data. Examples include content systems, internal tools, marketplaces, and account-based services. A static site may need less machinery. A browser application that only consumes an existing API may need a client framework instead.

Follow one request

Start with the request-response cycle:

browser request
    -> middleware
    -> URL configuration
    -> view
    -> model and other services
    -> template or another response format
    -> HTTP response

A URL configuration, often shortened to URLconf, maps a path pattern to a view. A view is Python code that accepts a request and returns a response. The view can query models, validate input, call application services, and render a template.

Middleware wraps this cycle. It can inspect or change requests before the view runs. It can also inspect or change responses on the way out. Django uses middleware for cross-cutting behavior such as sessions, authentication, security headers, and Cross-Site Request Forgery protection.

This map helps you place code. URL selection belongs in the URLconf. Request-specific orchestration belongs in a view. Data rules belong near models or application services. Presentation belongs in templates.

Separate the project from its apps

A Django project is one configured web application. It holds settings, the root URLconf, and server entry points.

A Django app is a Python package that provides one focused capability. A project can contain several apps. An app can also be designed for reuse in other projects.

Think of the project as the deployment boundary and apps as feature boundaries. An online store might have catalog, checkout, and accounts apps. Avoid creating an app for every model. Split by cohesive behavior and ownership.

The INSTALLED_APPS setting tells Django which applications participate in the project. Installed apps can contribute models, migrations, templates, static files, commands, and configuration.

Model data in Python

A Django model is a Python class that describes stored data. Model fields describe values and relationships. Django's object-relational mapper, or ORM, turns model operations into database queries.

from django.db import models


class Article(models.Model):
    title = models.CharField(max_length=200)
    published_at = models.DateTimeField(null=True, blank=True)

Each model usually maps to one database table. Each field usually maps to a column. A QuerySet represents a database query and the collection of model objects it can return.

Models are more than table declarations. They can hold validation, relationships, metadata, and behavior that belongs to the data concept. Keep request details out of them.

Changing a model class does not directly change a deployed database. Django records schema changes as migrations. makemigrations creates migration files from model changes. migrate applies the migration history to a database. Review migration files because schema changes affect real data and deployment order.

The ORM improves portability and makes common queries readable. It does not remove the need to understand SQL behavior. QuerySets can cause too many queries, load unnecessary rows, or hold transactions open. Inspect queries and database plans when performance matters.

Route URLs to views

Django checks URL patterns in order and stops at the first match. A pattern can capture values such as an integer identifier and pass them to the selected view.

Use app-level URLconfs and include them from the project URLconf. This keeps each feature's public paths near that feature. Name URL patterns so templates and Python code can reverse a name into a URL. Named reversal avoids scattering literal paths throughout the codebase.

A function-based view makes the request flow explicit. A class-based view can reuse framework behavior through inheritance and mixins. Neither form is automatically better. Choose the clearest form for the behavior, and avoid inheritance chains that hide control flow.

Views must return an HttpResponse or raise an exception such as Http404. The render shortcut combines a template with a context dictionary and returns an HTML response. Django can also return JSON, redirects, files, streaming responses, and custom status codes.

Render data with templates

A Django template combines static text with variables, tags, filters, and inheritance. Templates receive a context from a view and produce text, usually HTML.

Template variables display values. Tags provide presentation control such as loops and conditions. Filters transform displayed values. Template inheritance lets a base template define shared structure while child templates fill named blocks.

Django templates are intentionally not general-purpose Python. Keep database writes and business decisions out of templates. Prepare the data in Python, then let the template describe its presentation.

Django escapes variable output in HTML templates by default. That protection has boundaries. Marking untrusted content as safe, constructing unsafe HTML, or mishandling attributes can create Cross-Site Scripting risk. Treat auto-escaping as one control, not permission to ignore output context.

Accept input through forms

Django forms turn submitted data into a validation process. A form defines fields, converts input to Python values, reports errors, and exposes cleaned data after successful validation.

A ModelForm can derive fields from a model and save a model instance. Use explicit field lists so a later model change does not expose an unintended field.

Handle state-changing requests with POST or another suitable method. Include a CSRF token in internal POST forms. After a successful change, redirect rather than rendering the success page directly. This post-redirect-get pattern reduces accidental duplicate submissions after a refresh.

Browser validation helps the user, but the server remains the trust boundary. Validate authorization and domain rules on the server even when the interface already checked them.

Use the admin as an operations interface

Django can create an administrative interface from registered models. Authorized staff can add, change, and delete records through it.

The admin is a strong fit for trusted operational users and data management. It is not a default public product interface. Public workflows often need different permissions, language, layout, and business rules.

Admin access still needs careful authorization. Register only suitable models. Restrict object access where necessary. Review actions that can change many records.

Test behavior at boundaries

Django's test tools can create requests, exercise views, inspect responses, and use a separate test database. Tests should cover model rules, URL behavior, permissions, forms, templates, and important user flows.

Test the outcome that matters. A permission test should prove that an unauthorized user is denied and an authorized user succeeds. A form test should cover valid data and meaningful failures. Avoid tests that only duplicate the implementation line by line.

Database tests need deliberate query checks. Correct output can still hide an inefficient query pattern. Use query-count assertions or profiling when a view loads related objects.

Know the security boundary

Django includes protections for Cross-Site Scripting, Cross-Site Request Forgery, SQL injection through parameterized QuerySets, clickjacking, and secure transport configuration. These protections depend on correct use and deployment settings.

Raw SQL, unsafe template output, missing authorization, exposed secrets, and incorrect proxy settings can cross those boundaries. Keep SECRET_KEY secret. Never run production with DEBUG enabled. Set allowed hosts. Enforce HTTPS where the application handles authenticated or sensitive traffic. Run Django's deployment checks before release.

Django's development server is for development only. Production needs a WSGI or ASGI server, static-file handling, secure configuration, logging, backups, monitoring, and a deployment process.

Choose Django deliberately

Django is a useful choice when you want a mature, integrated Python stack and a server-rendered or API-backed application. Its ORM, admin, forms, authentication, and security defaults reduce repeated infrastructure work.

It may be a poor fit when the task is only a static page, when an existing service already owns all backend behavior, or when the team cannot support Python and Django operations. The framework also does not choose your domain model, authorization policy, database indexes, or deployment architecture for you.

A practical learning path

  1. Trace a request through a URLconf, view, template, and response.
  2. Separate project configuration from app-level features.
  3. Define a model, create migrations, and query it with QuerySets.
  4. Build forms with validation and a redirect after successful POST requests.
  5. Add authentication and object-level authorization to a real workflow.
  6. Register operational data in the admin and limit staff access.
  7. Test models, views, forms, permissions, and query behavior.
  8. Study security guidance and the deployment checklist before release.
  9. Learn transactions, query optimization, caching, asynchronous views, and background work as the application needs them.