0) Prereqs
- Install: Python 3.11+, Git, pip (comes with Python).
- Optional but recommended: PostgreSQL (for production), Docker (for containers), Node.js (if you’ll bundle front-end assets).
1) Create a project folder & virtual env
# pick a folder
mkdir mysite && cd mysite
# create & activate venv (Windows)
python -m venv .venv
.venv\Scripts\activate
# macOS/Linux:
# python3 -m venv .venv
# source .venv/bin/activate2) Install Django and essentials
pip install --upgrade pip
pip install django psycopg[binary] python-decouple gunicorn whitenoise
Why:
psycopgfor PostgreSQL (optional now, useful later).python-decouplefor.envvariables.gunicorn/whitenoisefor production.
3) Start the Django project
django-admin startproject config .
Tree now:
mysite/
config/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py
manage.py
4) Run it once
python manage.py runserver
Open http://127.0.0.1:8000 — you should see “The install worked!”
5) Create your first app
python manage.py startapp blog
Add blog to INSTALLED_APPS in config/settings.py.
6) Make a simple model (CRUD ready)
blog/models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
body = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
published = models.BooleanField(default=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return self.title
Apply migrations:
python manage.py makemigrations
python manage.py migrate
Create a superuser:
python manage.py createsuperuser
7) Register in the admin
blog/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ("title", "author", "published", "created")
prepopulated_fields = {"slug": ("title",)}
search_fields = ("title", "body")
list_filter = ("published", "created")
8) URLs, views, templates
Create app URLs:blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="post_list"),
path("<slug:slug>/", views.post_detail, name="post_detail"),
]
Wire them in project URLs:config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("blog.urls")),
]
Now visit http://127.0.0.1:8000/admin and add a Post.
Views:blog/views.py
from django.shortcuts import get_object_or_404, render
from .models import Post
def post_list(request):
posts = Post.objects.filter(published=True)
return render(request, "blog/post_list.html", {"posts": posts})
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug, published=True)
return render(request, "blog/post_detail.html", {"post": post})
Templates:
Create templates/blog/post_list.html:
<!doctype html>
<html>
<head><meta charset="utf-8"><title>Blog</title></head>
<body>
<h1>Posts</h1>
<ul>
{% for p in posts %}
<li><a href="{{ p.get_absolute_url|default:'/'|add:p.slug|add:'/' }}">{{ p.title }}</a></li>
{% empty %}
<li>No posts yet.</li>
{% endfor %}
</ul>
</body>
</html>
Create templates/blog/post_detail.html:
<!doctype html>
<html>
<head><meta charset="utf-8"><title>{{ post.title }}</title></head>
<body>
<a href="/">← Back</a>
<h1>{{ post.title }}</h1>
<p><small>By {{ post.author }} — {{ post.created|date:"Y-m-d H:i" }}</small></p>
<div>{{ post.body|linebreaks }}</div>
</body>
</html>
Tell Django where templates live:config/settings.py
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES[0]["DIRS"] = [BASE_DIR / "templates"]
9) Static & media (images, CSS, JS)
config/settings.py
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"] # for dev
STATIC_ROOT = BASE_DIR / "staticfiles" # for collectstatic (prod)
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"
During development:config/urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Create folders:
mkdir static media templates
mkdir templates/blog static/css static/js
10) Frontend
Navigate to http://127.0.0.1:8000/ you should see the published posts.
💬 Comments
No comments yet. Be the first to comment!
Login to comment.