Building a Project Budget Manager with Django (9 Part Series)
1 Deploying a Django Application ON “pythonanywhere”.
2 Project Budget Manager Tutorial Series
… 5 more parts…
3 Part 7: Deploying to PythonAnywhere
4 Building a Project Budget Manager with Django – Part 6: Advanced Features
5 Building a Project Budget Manager with Django – Part 5: Templates and Documentation
6 Building a Project Budget Manager with Django – Part 4: Deployment and Production Setup On Ubuntu Server
7 Building a Project Budget Manager with Django – Part 3: Views and Templates
8 Building a Project Budget Manager with Django – Part 2: Authentication and Models
9 Building a Project Budget Manager with Django – Part 1: Project Setup and Structure
Introduction
Welcome to the Django Project Budget Manager tutorial series! This guide is designed for beginners who want to learn Django by building a practical project management application. We’ll walk through each step in detail, explaining not just what to do, but why we’re doing it.
Getting the Project Template
To get started quickly, you can use(create a copy of the project template in your github without commits) our project template from GitHub:
<span># Use the project template</span>https://github.com/ChrisDevCode-Technologies/django-starter.git<span>#Click "use template" button at the top right corner which will provide you with a copy of the project template</span><span>#clone the repository you created using the template</span>git clone https://github.com/your_github_username/django-starter.git<span># Navigate to the project directory</span><span>cd </span>django-starter<span># Create a virtual environment</span>python <span>-m</span> venv venv<span># Activate the virtual environment</span><span># On Windows:</span>venv<span>\S</span>cripts<span>\a</span>ctivate<span># On macOS/Linux:</span><span>source </span>venv/bin/activate<span># Install dependencies</span>pip <span>install</span> <span>-r</span> requirements.txt<span># Use the project template</span> https://github.com/ChrisDevCode-Technologies/django-starter.git <span>#Click "use template" button at the top right corner which will provide you with a copy of the project template</span> <span>#clone the repository you created using the template</span> git clone https://github.com/your_github_username/django-starter.git <span># Navigate to the project directory</span> <span>cd </span>django-starter <span># Create a virtual environment</span> python <span>-m</span> venv venv <span># Activate the virtual environment</span> <span># On Windows:</span> venv<span>\S</span>cripts<span>\a</span>ctivate <span># On macOS/Linux:</span> <span>source </span>venv/bin/activate <span># Install dependencies</span> pip <span>install</span> <span>-r</span> requirements.txt# Use the project template https://github.com/ChrisDevCode-Technologies/django-starter.git #Click "use template" button at the top right corner which will provide you with a copy of the project template #clone the repository you created using the template git clone https://github.com/your_github_username/django-starter.git # Navigate to the project directory cd django-starter # Create a virtual environment python -m venv venv # Activate the virtual environment # On Windows: venv\Scripts\activate # On macOS/Linux: source venv/bin/activate # Install dependencies pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode
Project Structure
Our project follows a clean and organized structure. Here’s what each directory and file is for:
django-starter/├── app/ # Main application directory│ ├── migrations/ # Database migrations│ ├── static/ # Static files (CSS, JS, images)│ ├── templates/ # HTML templates│ ├── __init__.py # Makes this directory a Python package│ ├── admin.py # Admin interface configuration│ ├── apps.py # App configuration│ ├── forms.py # Form definitions│ ├── models.py # Database models│ ├── tests.py # Unit tests│ ├── urls.py # URL routing for the app│ └── views.py # View functions/classes├── config/ # Project configuration directory│ ├── __init__.py│ ├── asgi.py # ASGI configuration for async servers│ ├── settings.py # Project settings│ ├── urls.py # Main URL routing│ └── wsgi.py # WSGI configuration for web servers├── docs/ # Documentation directory├── static/ # Project-level static files├── templates/ # Project-level templates├── .env # Environment variables (create this)├── .gitignore # Git ignore file├── manage.py # Django management script└── requirements.txt # Project dependenciesdjango-starter/ ├── app/ # Main application directory │ ├── migrations/ # Database migrations │ ├── static/ # Static files (CSS, JS, images) │ ├── templates/ # HTML templates │ ├── __init__.py # Makes this directory a Python package │ ├── admin.py # Admin interface configuration │ ├── apps.py # App configuration │ ├── forms.py # Form definitions │ ├── models.py # Database models │ ├── tests.py # Unit tests │ ├── urls.py # URL routing for the app │ └── views.py # View functions/classes ├── config/ # Project configuration directory │ ├── __init__.py │ ├── asgi.py # ASGI configuration for async servers │ ├── settings.py # Project settings │ ├── urls.py # Main URL routing │ └── wsgi.py # WSGI configuration for web servers ├── docs/ # Documentation directory ├── static/ # Project-level static files ├── templates/ # Project-level templates ├── .env # Environment variables (create this) ├── .gitignore # Git ignore file ├── manage.py # Django management script └── requirements.txt # Project dependenciesdjango-starter/ ├── app/ # Main application directory │ ├── migrations/ # Database migrations │ ├── static/ # Static files (CSS, JS, images) │ ├── templates/ # HTML templates │ ├── __init__.py # Makes this directory a Python package │ ├── admin.py # Admin interface configuration │ ├── apps.py # App configuration │ ├── forms.py # Form definitions │ ├── models.py # Database models │ ├── tests.py # Unit tests │ ├── urls.py # URL routing for the app │ └── views.py # View functions/classes ├── config/ # Project configuration directory │ ├── __init__.py │ ├── asgi.py # ASGI configuration for async servers │ ├── settings.py # Project settings │ ├── urls.py # Main URL routing │ └── wsgi.py # WSGI configuration for web servers ├── docs/ # Documentation directory ├── static/ # Project-level static files ├── templates/ # Project-level templates ├── .env # Environment variables (create this) ├── .gitignore # Git ignore file ├── manage.py # Django management script └── requirements.txt # Project dependencies
Enter fullscreen mode Exit fullscreen mode
Environment Setup
- Create a
.env
file in your project root:
<span># .env</span><span>DEBUG</span><span>=</span>True<span>SECRET_KEY</span><span>=</span>your-secret-key-here<span>ALLOWED_HOSTS</span><span>=</span>localhost,127.0.0.1<span>DATABASE_URL</span><span>=</span>sqlite:///db.sqlite3<span># .env</span> <span>DEBUG</span><span>=</span>True <span>SECRET_KEY</span><span>=</span>your-secret-key-here <span>ALLOWED_HOSTS</span><span>=</span>localhost,127.0.0.1 <span>DATABASE_URL</span><span>=</span>sqlite:///db.sqlite3# .env DEBUG=True SECRET_KEY=your-secret-key-here ALLOWED_HOSTS=localhost,127.0.0.1 DATABASE_URL=sqlite:///db.sqlite3
Enter fullscreen mode Exit fullscreen mode
- Update
settings.py
to use environment variables:
<span># config/settings.py </span><span>import</span> <span>os</span><span>from</span> <span>pathlib</span> <span>import</span> <span>Path</span><span>from</span> <span>dotenv</span> <span>import</span> <span>load_dotenv</span><span># Load environment variables </span><span>load_dotenv</span><span>()</span><span># Build paths inside the project </span><span>BASE_DIR</span> <span>=</span> <span>Path</span><span>(</span><span>__file__</span><span>).</span><span>resolve</span><span>().</span><span>parent</span><span>.</span><span>parent</span><span># SECURITY WARNING: keep the secret key used in production secret! </span><span>SECRET_KEY</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>SECRET_KEY</span><span>'</span><span>)</span><span># SECURITY WARNING: don't run with debug turned on in production! </span><span>DEBUG</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>DEBUG</span><span>'</span><span>,</span> <span>'</span><span>False</span><span>'</span><span>)</span> <span>==</span> <span>'</span><span>True</span><span>'</span><span>ALLOWED_HOSTS</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>ALLOWED_HOSTS</span><span>'</span><span>,</span> <span>''</span><span>).</span><span>split</span><span>(</span><span>'</span><span>,</span><span>'</span><span>)</span><span># Application definition </span><span>INSTALLED_APPS</span> <span>=</span> <span>[</span><span>'</span><span>django.contrib.admin</span><span>'</span><span>,</span><span>'</span><span>django.contrib.auth</span><span>'</span><span>,</span><span>'</span><span>django.contrib.contenttypes</span><span>'</span><span>,</span><span>'</span><span>django.contrib.sessions</span><span>'</span><span>,</span><span>'</span><span>django.contrib.messages</span><span>'</span><span>,</span><span>'</span><span>django.contrib.staticfiles</span><span>'</span><span>,</span><span>'</span><span>app.apps.AppConfig</span><span>'</span><span>,</span> <span># Our main application </span><span>]</span><span># ... rest of the settings ... </span><span># config/settings.py </span> <span>import</span> <span>os</span> <span>from</span> <span>pathlib</span> <span>import</span> <span>Path</span> <span>from</span> <span>dotenv</span> <span>import</span> <span>load_dotenv</span> <span># Load environment variables </span><span>load_dotenv</span><span>()</span> <span># Build paths inside the project </span><span>BASE_DIR</span> <span>=</span> <span>Path</span><span>(</span><span>__file__</span><span>).</span><span>resolve</span><span>().</span><span>parent</span><span>.</span><span>parent</span> <span># SECURITY WARNING: keep the secret key used in production secret! </span><span>SECRET_KEY</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>SECRET_KEY</span><span>'</span><span>)</span> <span># SECURITY WARNING: don't run with debug turned on in production! </span><span>DEBUG</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>DEBUG</span><span>'</span><span>,</span> <span>'</span><span>False</span><span>'</span><span>)</span> <span>==</span> <span>'</span><span>True</span><span>'</span> <span>ALLOWED_HOSTS</span> <span>=</span> <span>os</span><span>.</span><span>getenv</span><span>(</span><span>'</span><span>ALLOWED_HOSTS</span><span>'</span><span>,</span> <span>''</span><span>).</span><span>split</span><span>(</span><span>'</span><span>,</span><span>'</span><span>)</span> <span># Application definition </span><span>INSTALLED_APPS</span> <span>=</span> <span>[</span> <span>'</span><span>django.contrib.admin</span><span>'</span><span>,</span> <span>'</span><span>django.contrib.auth</span><span>'</span><span>,</span> <span>'</span><span>django.contrib.contenttypes</span><span>'</span><span>,</span> <span>'</span><span>django.contrib.sessions</span><span>'</span><span>,</span> <span>'</span><span>django.contrib.messages</span><span>'</span><span>,</span> <span>'</span><span>django.contrib.staticfiles</span><span>'</span><span>,</span> <span>'</span><span>app.apps.AppConfig</span><span>'</span><span>,</span> <span># Our main application </span><span>]</span> <span># ... rest of the settings ... </span># config/settings.py import os from pathlib import Path from dotenv import load_dotenv # Load environment variables load_dotenv() # Build paths inside the project BASE_DIR = Path(__file__).resolve().parent.parent # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = os.getenv('DEBUG', 'False') == 'True' ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '').split(',') # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app.apps.AppConfig', # Our main application ] # ... rest of the settings ...
Enter fullscreen mode Exit fullscreen mode
URL Configuration
Let’s set up the URL routing:
<span># config/urls.py </span><span>from</span> <span>django.contrib</span> <span>import</span> <span>admin</span><span>from</span> <span>django.urls</span> <span>import</span> <span>path</span><span>,</span> <span>include</span><span>from</span> <span>django.conf</span> <span>import</span> <span>settings</span><span>from</span> <span>django.conf.urls.static</span> <span>import</span> <span>static</span><span>urlpatterns</span> <span>=</span> <span>[</span><span># Admin interface URLs </span> <span>path</span><span>(</span><span>'</span><span>admin/</span><span>'</span><span>,</span> <span>admin</span><span>.</span><span>site</span><span>.</span><span>urls</span><span>),</span><span># Our app URLs </span> <span>path</span><span>(</span><span>''</span><span>,</span> <span>include</span><span>(</span><span>'</span><span>app.urls</span><span>'</span><span>)),</span><span>]</span> <span>+</span> <span>static</span><span>(</span><span>settings</span><span>.</span><span>MEDIA_URL</span><span>,</span> <span>document_root</span><span>=</span><span>settings</span><span>.</span><span>MEDIA_ROOT</span><span>)</span><span># config/urls.py </span> <span>from</span> <span>django.contrib</span> <span>import</span> <span>admin</span> <span>from</span> <span>django.urls</span> <span>import</span> <span>path</span><span>,</span> <span>include</span> <span>from</span> <span>django.conf</span> <span>import</span> <span>settings</span> <span>from</span> <span>django.conf.urls.static</span> <span>import</span> <span>static</span> <span>urlpatterns</span> <span>=</span> <span>[</span> <span># Admin interface URLs </span> <span>path</span><span>(</span><span>'</span><span>admin/</span><span>'</span><span>,</span> <span>admin</span><span>.</span><span>site</span><span>.</span><span>urls</span><span>),</span> <span># Our app URLs </span> <span>path</span><span>(</span><span>''</span><span>,</span> <span>include</span><span>(</span><span>'</span><span>app.urls</span><span>'</span><span>)),</span> <span>]</span> <span>+</span> <span>static</span><span>(</span><span>settings</span><span>.</span><span>MEDIA_URL</span><span>,</span> <span>document_root</span><span>=</span><span>settings</span><span>.</span><span>MEDIA_ROOT</span><span>)</span># config/urls.py from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # Admin interface URLs path('admin/', admin.site.urls), # Our app URLs path('', include('app.urls')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Enter fullscreen mode Exit fullscreen mode
<span># app/urls.py </span><span>from</span> <span>django.urls</span> <span>import</span> <span>path</span><span>from</span> <span>.</span> <span>import</span> <span>views</span><span>app_name</span> <span>=</span> <span>'</span><span>app</span><span>'</span> <span># Namespace for our URLs </span><span>urlpatterns</span> <span>=</span> <span>[</span><span># Home page </span> <span>path</span><span>(</span><span>''</span><span>,</span> <span>views</span><span>.</span><span>dashboard_view</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>dashboard</span><span>'</span><span>),</span><span># Project URLs </span> <span>path</span><span>(</span><span>'</span><span>projects/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_list</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_list</span><span>'</span><span>),</span><span>path</span><span>(</span><span>'</span><span>projects/create/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_create</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_create</span><span>'</span><span>),</span><span>path</span><span>(</span><span>'</span><span>projects/<int:pk>/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_detail</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_detail</span><span>'</span><span>),</span><span># ... more URL patterns will be added later ... </span><span>]</span><span># app/urls.py </span> <span>from</span> <span>django.urls</span> <span>import</span> <span>path</span> <span>from</span> <span>.</span> <span>import</span> <span>views</span> <span>app_name</span> <span>=</span> <span>'</span><span>app</span><span>'</span> <span># Namespace for our URLs </span> <span>urlpatterns</span> <span>=</span> <span>[</span> <span># Home page </span> <span>path</span><span>(</span><span>''</span><span>,</span> <span>views</span><span>.</span><span>dashboard_view</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>dashboard</span><span>'</span><span>),</span> <span># Project URLs </span> <span>path</span><span>(</span><span>'</span><span>projects/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_list</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_list</span><span>'</span><span>),</span> <span>path</span><span>(</span><span>'</span><span>projects/create/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_create</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_create</span><span>'</span><span>),</span> <span>path</span><span>(</span><span>'</span><span>projects/<int:pk>/</span><span>'</span><span>,</span> <span>views</span><span>.</span><span>project_detail</span><span>,</span> <span>name</span><span>=</span><span>'</span><span>project_detail</span><span>'</span><span>),</span> <span># ... more URL patterns will be added later ... </span><span>]</span># app/urls.py from django.urls import path from . import views app_name = 'app' # Namespace for our URLs urlpatterns = [ # Home page path('', views.dashboard_view, name='dashboard'), # Project URLs path('projects/', views.project_list, name='project_list'), path('projects/create/', views.project_create, name='project_create'), path('projects/<int:pk>/', views.project_detail, name='project_detail'), # ... more URL patterns will be added later ... ]
Enter fullscreen mode Exit fullscreen mode
Database Configuration
By default, we’re using SQLite for development. The database configuration is in settings.py
:
<span># config/settings.py </span><span>DATABASES</span> <span>=</span> <span>{</span><span>'</span><span>default</span><span>'</span><span>:</span> <span>{</span><span>'</span><span>ENGINE</span><span>'</span><span>:</span> <span>'</span><span>django.db.backends.sqlite3</span><span>'</span><span>,</span><span>'</span><span>NAME</span><span>'</span><span>:</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>db.sqlite3</span><span>'</span><span>,</span><span>}</span><span>}</span><span># config/settings.py </span> <span>DATABASES</span> <span>=</span> <span>{</span> <span>'</span><span>default</span><span>'</span><span>:</span> <span>{</span> <span>'</span><span>ENGINE</span><span>'</span><span>:</span> <span>'</span><span>django.db.backends.sqlite3</span><span>'</span><span>,</span> <span>'</span><span>NAME</span><span>'</span><span>:</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>db.sqlite3</span><span>'</span><span>,</span> <span>}</span> <span>}</span># config/settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
Enter fullscreen mode Exit fullscreen mode
Static and Media Files
Configure static and media files in settings.py
:
<span># config/settings.py </span><span># Static files (CSS, JavaScript, Images) </span><span>STATIC_URL</span> <span>=</span> <span>'</span><span>/static/</span><span>'</span><span>STATICFILES_DIRS</span> <span>=</span> <span>[</span><span>BASE_DIR</span> <span>/</span> <span>'</span><span>static</span><span>'</span><span>]</span><span>STATIC_ROOT</span> <span>=</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>staticfiles</span><span>'</span><span># Media files (User uploads) </span><span>MEDIA_URL</span> <span>=</span> <span>'</span><span>/media/</span><span>'</span><span>MEDIA_ROOT</span> <span>=</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>media</span><span>'</span><span># config/settings.py </span> <span># Static files (CSS, JavaScript, Images) </span><span>STATIC_URL</span> <span>=</span> <span>'</span><span>/static/</span><span>'</span> <span>STATICFILES_DIRS</span> <span>=</span> <span>[</span><span>BASE_DIR</span> <span>/</span> <span>'</span><span>static</span><span>'</span><span>]</span> <span>STATIC_ROOT</span> <span>=</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>staticfiles</span><span>'</span> <span># Media files (User uploads) </span><span>MEDIA_URL</span> <span>=</span> <span>'</span><span>/media/</span><span>'</span> <span>MEDIA_ROOT</span> <span>=</span> <span>BASE_DIR</span> <span>/</span> <span>'</span><span>media</span><span>'</span># config/settings.py # Static files (CSS, JavaScript, Images) STATIC_URL = '/static/' STATICFILES_DIRS = [BASE_DIR / 'static'] STATIC_ROOT = BASE_DIR / 'staticfiles' # Media files (User uploads) MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
Enter fullscreen mode Exit fullscreen mode
Initial Setup Commands
Run these commands to set up your database and create a superuser:
<span># Make migrations</span>python manage.py makemigrations<span># Apply migrations</span>python manage.py migrate<span># Create a superuser (admin)</span>python manage.py createsuperuser<span># Run the development server</span>python manage.py runserver<span># Make migrations</span> python manage.py makemigrations <span># Apply migrations</span> python manage.py migrate <span># Create a superuser (admin)</span> python manage.py createsuperuser <span># Run the development server</span> python manage.py runserver# Make migrations python manage.py makemigrations # Apply migrations python manage.py migrate # Create a superuser (admin) python manage.py createsuperuser # Run the development server python manage.py runserver
Enter fullscreen mode Exit fullscreen mode
Testing the Setup
- Visit
http://127.0.0.1:8000/
– You should see the default landing page - Visit
http://127.0.0.1:8000/admin/
– You should be able to log in with your superuser credentials
Next Steps
In Part 2, we’ll create our database models and set up the Django admin interface. We’ll define the structure for our projects, tasks, and user profiles.
Common Issues and Solutions
-
ModuleNotFoundError: No module named ‘dotenv’
- Solution: Run
pip install python-dotenv
- Solution: Run
-
Database migration errors
- Solution: Delete the
db.sqlite3
file and all files inmigrations
folders (except__init__.py
), then run migrations again
- Solution: Delete the
-
Static files not loading
- Solution: Make sure
DEBUG=True
in development - Run
python manage.py collectstatic
- Solution: Make sure
-
Import errors
- Solution: Make sure your virtual environment is activated
- Check that all requirements are installed:
pip install -r requirements.txt
Additional Resources
Remember to never commit sensitive information like secret keys or database credentials to version control. Always use environment variables for such data.
Continue to Part 2: Authentication and Models to learn how to implement user authentication and create our data models.
Building a Project Budget Manager with Django (9 Part Series)
1 Deploying a Django Application ON “pythonanywhere”.
2 Project Budget Manager Tutorial Series
… 5 more parts…
3 Part 7: Deploying to PythonAnywhere
4 Building a Project Budget Manager with Django – Part 6: Advanced Features
5 Building a Project Budget Manager with Django – Part 5: Templates and Documentation
6 Building a Project Budget Manager with Django – Part 4: Deployment and Production Setup On Ubuntu Server
7 Building a Project Budget Manager with Django – Part 3: Views and Templates
8 Building a Project Budget Manager with Django – Part 2: Authentication and Models
9 Building a Project Budget Manager with Django – Part 1: Project Setup and Structure
原文链接:Building a Project Budget Manager with Django – Part 1: Project Setup and Structure
暂无评论内容