Monday, August 18, 2025
0 comments

Master Python for Web Applications: Module 9 - Build Dynamic Websites and APIs with Flask, Django, and More

Welcome to Module 9 of our comprehensive Python course, designed to transform you from a beginner to an advanced Python programmer! 
In Module 8, we explored desktop application development with Tkinter, creating user-friendly GUIs. Now, we dive into Python for web applications, focusing on Flask and Django, two powerful web frameworks. This module covers introduction to web frameworks, Flask basics (routes, templates, forms), Django basics (models, views, templates, ORM), REST API development, authentication and sessions, and deployment basics using platforms like Heroku and PythonAnywhere.This blog is beginner-friendly yet detailed enough for intermediate and advanced learners, offering real-world scenarios, multiple code examples, pros and cons, best practices, and alternatives. Whether you're building a blog, an e-commerce platform, or a RESTful API, this guide will equip you with the skills to create modern, scalable web applications. Let’s dive in!
Table of Contents
  1. Introduction to Web Frameworks (Flask & Django)
    • What Are Web Frameworks?
    • Flask vs. Django: Key Differences
    • Real-World Applications
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Setting Up Flask and Django Projects
  2. Flask Basics (Routes, Templates, Forms)
    • Creating Routes
    • Rendering Templates
    • Handling Forms
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Building a Task Management App
  3. Django Basics (Models, Views, Templates, ORM)
    • Defining Models
    • Creating Views and Templates
    • Using Django’s ORM
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Developing a Blog Application
  4. REST API Development with Flask/Django
    • Building REST APIs
    • Handling HTTP Methods
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Creating a Task API
  5. Authentication & Sessions
    • User Authentication
    • Managing Sessions
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Adding Login to a Web App
  6. Deployment Basics (Heroku, PythonAnywhere)
    • Preparing Apps for Deployment
    • Deploying to Heroku and PythonAnywhere
    • Pros, Cons, and Alternatives
    • Best Practices
    • Example: Deploying a Flask and Django App
  7. Conclusion & Next Steps

1. Introduction to Web Frameworks (Flask & Django)What Are Web Frameworks?Web frameworks simplify the development of web applications by providing tools for routing, templating, database interactions, and more. Flask is a lightweight, micro-framework, ideal for small to medium projects. Django is a full-stack framework with batteries included, suited for complex, database-driven applications.Flask Example:
python
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, Flask!"

if __name__ == '__main__':
    app.run(debug=True)
Django Example (requires project setup):
bash
django-admin startproject myproject
cd myproject
python manage.py startapp myapp
Flask vs. Django: Key Differences
Feature
Flask
Django
Type
Micro-framework
Full-stack framework
Complexity
Simple, flexible
Structured, opinionated
Database
No built-in ORM
Built-in ORM
Use Case
Small apps, APIs
Large, database-driven apps
Real-World Applications
  • Flask: Personal blogs, small APIs, dashboards.
  • Django: E-commerce platforms, CMS, social networks.
  • Both: Prototyping, enterprise applications.
Pros, Cons, and AlternativesPros:
  • Flask: Lightweight, easy to learn, highly customizable.
  • Django: Rapid development, robust security, built-in admin interface.
  • Both support Python’s ecosystem and community.
Cons:
  • Flask: Requires manual setup for complex features (e.g., ORM).
  • Django: Steeper learning curve, less flexible for non-standard apps.
  • Both require additional libraries for advanced features.
Alternatives:
  • FastAPI: For high-performance, async APIs.
  • Bottle: For ultra-lightweight projects.
  • Tornado: For asynchronous web apps.
Best Practices:
  • Choose Flask for small, custom projects; Django for large, structured apps.
  • Follow RESTful principles for APIs.
  • Use virtual environments to manage dependencies.
  • Adhere to PEP 8 for clean, readable code.
Example: Setting Up Flask and Django ProjectsFlask Setup:
  1. Install Flask:
    bash
    pip install flask
  2. Create app.py:
python
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return "<h1>Welcome to Flask!</h1>"

if __name__ == '__main__':
    app.run(debug=True)
  1. Run: python app.py
Django Setup:
  1. Install Django:
    bash
    pip install django
  2. Create project:
    bash
    django-admin startproject myproject
    cd myproject
    python manage.py startapp myapp
  3. Update myproject/settings.py:
python
INSTALLED_APPS = [
    ...
    'myapp',
]
  1. Create myapp/views.py:
python
from django.http import HttpResponse

def home(request):
    return HttpResponse("<h1>Welcome to Django!</h1>")
  1. Update myproject/urls.py:
python
from django.urls import path
from myapp.views import home

urlpatterns = [
    path('', home, name='home'),
]
  1. Run: python manage.py runserver
Output: Both apps display a welcome message at http://localhost:5000 (Flask) or http://localhost:8000 (Django).This example sets up basic Flask and Django projects, demonstrating their initial structure and usage.
2. Flask Basics (Routes, Templates, Forms)Creating RoutesRoutes map URLs to functions using the @app.route() decorator.Example:
python
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return "Home Page"

@app.route('/about')
def about():
    return "About Page"

if __name__ == '__main__':
    app.run(debug=True)
Rendering TemplatesFlask uses Jinja2 for templating, allowing dynamic HTML rendering.Example (templates/index.html):
html
<!DOCTYPE html>
<html>
<head><title>Home</title></head>
<body>
    <h1>Welcome, {{ name }}!</h1>
</body>
</html>
Python Code:
python
from flask import Flask, render_template
app = Flask(__name__)

@app.route('/user/<name>')
def user(name):
    return render_template('index.html', name=name)
Handling FormsUse Flask-WTF for secure form handling.Example:
  1. Install: pip install flask-wtf
  2. Create forms.py:
python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class NameForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    submit = SubmitField('Submit')
  1. Update app.py:
python
from flask import Flask, render_template, request
from forms import NameForm

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

@app.route('/', methods=['GET', 'POST'])
def home():
    form = NameForm()
    if form.validate_on_submit():
        return f"Hello, {form.name.data}!"
    return render_template('form.html', form=form)
  1. Create templates/form.html:
html
<!DOCTYPE html>
<html>
<head><title>Form</title></head>
<body>
    <form method="POST">
        {{ form.hidden_tag() }}
        {{ form.name.label }} {{ form.name() }}
        {{ form.submit() }}
    </form>
</body>
</html>
Pros, Cons, and AlternativesPros:
  • Routes are simple and flexible.
  • Jinja2 templates are powerful for dynamic content.
  • Flask-WTF ensures secure form handling.
Cons:
  • Manual setup for forms and templates.
  • Limited built-in features compared to Django.
  • Requires additional extensions for advanced functionality.
Alternatives:
  • FastAPI: For async, modern APIs.
  • Bottle: For simpler routing and templating.
  • Django Forms: For integrated form handling.
Best Practices:
  • Use methods=['GET', 'POST'] for form routes.
  • Store templates in a templates folder.
  • Use SECRET_KEY for form security.
  • Validate forms server-side with Flask-WTF.
Example: Building a Task Management AppLet’s create a Flask app to manage tasks.
  1. Install dependencies: pip install flask flask-wtf
  2. Create forms.py:
python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class TaskForm(FlaskForm):
    task = StringField('Task Description', validators=[DataRequired()])
    submit = SubmitField('Add Task')
  1. Create app.py:
python
from flask import Flask, render_template, request, redirect, url_for
from forms import TaskForm

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
tasks = []

@app.route('/', methods=['GET', 'POST'])
def home():
    form = TaskForm()
    if form.validate_on_submit():
        tasks.append(form.task.data)
        return redirect(url_for('home'))
    return render_template('tasks.html', form=form, tasks=tasks)

@app.route('/delete/<int:task_id>')
def delete(task_id):
    if 0 <= task_id < len(tasks):
        tasks.pop(task_id)
    return redirect(url_for('home'))

if __name__ == '__main__':
    app.run(debug=True)
  1. Create templates/tasks.html:
html
<!DOCTYPE html>
<html>
<head><title>Task Manager</title></head>
<body>
    <h1>Task Manager</h1>
    <form method="POST">
        {{ form.hidden_tag() }}
        {{ form.task.label }} {{ form.task() }}
        {{ form.submit() }}
    </form>
    <ul>
        {% for i, task in tasks|enumerate %}
            <li>{{ task }} <a href="{{ url_for('delete', task_id=i) }}">Delete</a></li>
        {% endfor %}
    </ul>
</body>
</html>
Output: A task management app where users can add and delete tasks via a web interface.This example demonstrates Flask’s routing, templating, and form handling for a practical web application.
3. Django Basics (Models, Views, Templates, ORM)Defining ModelsDjango’s models define database tables using Python classes, with the ORM (Object-Relational Mapping) handling database interactions.Example (myapp/models.py):
python
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.title
Creating Views and TemplatesViews process requests and return responses, often rendering templates.Example (myapp/views.py):
python
from django.shortcuts import render
from .models import Post

def home(request):
    posts = Post.objects.all()
    return render_template('home.html', {'posts': posts})
Template (myapp/templates/home.html):
html
<!DOCTYPE html>
<html>
<head><title>Blog</title></head>
<body>
    <h1>Blog Posts</h1>
    {% for post in posts %}
        <h2>{{ post.title }}</h2>
        <p>{{ post.content }}</p>
    {% endfor %}
</body>
</html>
Using Django’s ORMThe ORM allows database queries without raw SQL:
  • Create: Post.objects.create(title="My Post", content="Content")
  • Read: Post.objects.all()
  • Update: post.title = "New Title"; post.save()
  • Delete: post.delete()
Pros, Cons, and AlternativesPros:
  • Models simplify database design.
  • ORM abstracts SQL for portability.
  • Templates integrate seamlessly with views.
Cons:
  • ORM can be slower for complex queries.
  • Django’s structure is less flexible than Flask.
  • Steeper learning curve for beginners.
Alternatives:
  • SQLAlchemy: For custom ORM with Flask.
  • Flask Templates: For lightweight templating.
  • FastAPI with Tortoise ORM: For async database operations.
Best Practices:
  • Define models with clear, descriptive fields.
  • Use Django’s template tags for logic ({% if %}, {% for %}).
  • Keep views thin, moving logic to models or utilities.
  • Run migrations after model changes: python manage.py makemigrations && python manage.py migrate.
Example: Developing a Blog ApplicationLet’s create a Django blog with posts.
  1. Set up project: django-admin startproject blogproject && cd blogproject && python manage.py startapp blog
  2. Update settings.py:
python
INSTALLED_APPS = [
    ...
    'blog',
]
  1. Create blog/models.py:
python
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.title
  1. Create blog/views.py:
python
from django.shortcuts import render, redirect
from .models import Post
from .forms import PostForm

def home(request):
    posts = Post.objects.all()
    return render(request, 'home.html', {'posts': posts})

def add_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('home')
    else:
        form = PostForm()
    return render(request, 'add_post.html', {'form': form})
  1. Create blog/forms.py:
python
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content']
  1. Update blogproject/urls.py:
python
from django.urls import path
from blog.views import home, add_post

urlpatterns = [
    path('', home, name='home'),
    path('add/', add_post, name='add_post'),
]
  1. Create blog/templates/home.html:
html
<!DOCTYPE html>
<html>
<head><title>Blog</title></head>
<body>
    <h1>My Blog</h1>
    <a href="{% url 'add_post' %}">Add Post</a>
    {% for post in posts %}
        <h2>{{ post.title }}</h2>
        <p>{{ post.content }}</p>
    {% endfor %}
</body>
</html>
  1. Create blog/templates/add_post.html:
html
<!DOCTYPE html>
<html>
<head><title>Add Post</title></head>
<body>
    <h1>Add New Post</h1>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Save</button>
    </form>
</body>
</html>
  1. Run migrations and server:
bash
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Output: A blog app at http://localhost:8000 where users can view and add posts.This example demonstrates Django’s models, views, templates, and ORM for a fully functional blog.
4. REST API Development with Flask/DjangoBuilding REST APIsREST APIs handle HTTP requests (GET, POST, PUT, DELETE) to provide data services.Flask REST API:
python
from flask import Flask, jsonify, request
app = Flask(__name__)

tasks = []

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify(tasks)

@app.route('/api/tasks', methods=['POST'])
def add_task():
    task = request.json
    tasks.append(task)
    return jsonify(task), 201
Django REST Framework (DRF):
  1. Install: pip install djangorestframework
  2. Update settings.py:
python
INSTALLED_APPS = [
    ...
    'rest_framework',
]
  1. Create blog/serializers.py:
python
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'created_at']
  1. Create blog/views.py (API view):
python
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
  1. Update blogproject/urls.py:
python
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from blog.views import PostViewSet

router = DefaultRouter()
router.register(r'posts', PostViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
    ...
]
Handling HTTP Methods
  • GET: Retrieve data.
  • POST: Create data.
  • PUT/PATCH: Update data.
  • DELETE: Remove data.
Pros, Cons, and AlternativesPros:
  • Flask: Lightweight, easy to customize for APIs.
  • Django REST Framework: Robust, with built-in authentication and serialization.
  • Both support JSON and RESTful standards.
Cons:
  • Flask: Requires manual setup for complex APIs.
  • DRF: Adds complexity and dependencies.
  • Both need additional security measures for production.
Alternatives:
  • FastAPI: For high-performance, async APIs.
  • Falcon: For minimalistic APIs.
  • Hug: For simple Python APIs.
Best Practices:
  • Use HTTP status codes (e.g., 201 for creation, 404 for not found).
  • Validate API inputs with libraries like marshmallow (Flask) or serializers (DRF).
  • Implement rate limiting for security.
  • Document APIs with tools like Swagger/OpenAPI.
Example: Creating a Task APIFlask Task API:
python
from flask import Flask, jsonify, request
app = Flask(__name__)

tasks = []
task_id = 0

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify(tasks)

@app.route('/api/tasks', methods=['POST'])
def add_task():
    global task_id
    task = request.json
    task['id'] = task_id
    task_id += 1
    tasks.append(task)
    return jsonify(task), 201

@app.route('/api/tasks/<int:id>', methods=['DELETE'])
def delete_task(id):
    global tasks
    tasks = [task for task in tasks if task['id'] != id]
    return jsonify({'message': 'Task deleted'}), 200

if __name__ == '__main__':
    app.run(debug=True)
Django Task API:
  1. Create blog/models.py:
python
from django.db import models

class Task(models.Model):
    description = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.description
  1. Create blog/serializers.py:
python
from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['id', 'description', 'created_at']
  1. Update blog/views.py:
python
from rest_framework import viewsets
from .models import Task
from .serializers import TaskSerializer

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
  1. Update blogproject/urls.py:
python
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from blog.views import TaskViewSet

router = DefaultRouter()
router.register(r'tasks', TaskViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]
  1. Run migrations and server:
bash
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Output: Both APIs support GET/POST/DELETE operations at http://localhost:5000/api/tasks (Flask) or http://localhost:8000/api/tasks/ (Django).This example creates a REST API for task management, demonstrating Flask and Django’s capabilities.
5. Authentication & SessionsUser AuthenticationAuthentication verifies user identity, typically with usernames and passwords.Flask Authentication (using flask-login):
  1. Install: pip install flask-login
  2. Update app.py:
python
from flask import Flask, render_template, request, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
login_manager = LoginManager(app)

class User(UserMixin):
    def __init__(self, id):
        self.id = id

users = {'admin': 'password'}

@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if users.get(username) == password:
            login_user(User(username))
            return redirect(url_for('dashboard'))
        return "Invalid credentials"
    return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
    return "Welcome to the Dashboard!"

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))
Django Authentication:
  1. Use Django’s built-in authentication:
python
# blog/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user:
            login(request, user)
            return redirect('dashboard')
        return render(request, 'login.html', {'error': 'Invalid credentials'})
    return render(request, 'login.html')

@login_required
def dashboard(request):
    return render(request, 'dashboard.html')

def logout_view(request):
    logout(request)
    return redirect('login')
  1. Update urls.py:
python
from django.urls import path
from blog.views import login_view, dashboard, logout_view

urlpatterns = [
    path('login/', login_view, name='login'),
    path('dashboard/', dashboard, name='dashboard'),
    path('logout/', logout_view, name='logout'),
]
Managing SessionsSessions store user data across requests, using cookies or server-side storage.Flask Sessions:
python
from flask import Flask, session

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

@app.route('/set')
def set_session():
    session['key'] = 'value'
    return "Session set"

@app.route('/get')
def get_session():
    return session.get('key', 'Not set')
Django Sessions:
python
# blog/views.py
def set_session(request):
    request.session['key'] = 'value'
    return HttpResponse("Session set")

def get_session(request):
    return HttpResponse(request.session.get('key', 'Not set'))
Pros, Cons, and AlternativesPros:
  • Flask: Flexible authentication with flask-login.
  • Django: Built-in authentication system with admin integration.
  • Sessions provide seamless user state management.
Cons:
  • Flask: Requires external libraries for authentication.
  • Django: Complex for custom authentication flows.
  • Sessions can be vulnerable to attacks if not secured.
Alternatives:
  • JWT: For token-based authentication.
  • OAuth: For third-party logins (e.g., Google).
  • FastAPI with JWT: For modern, async authentication.
Best Practices:
  • Use HTTPS to secure session cookies.
  • Hash passwords with bcrypt (Flask) or Django’s built-in hasher.
  • Implement CSRF protection for forms.
  • Expire sessions after inactivity.
Example: Adding Login to a Web AppFlask Login App:
  1. Install: pip install flask flask-login
  2. Create app.py:
python
from flask import Flask, render_template, request, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
login_manager = LoginManager(app)

class User(UserMixin):
    def __init__(self, id):
        self.id = id

users = {'admin': 'password'}

@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if users.get(username) == password:
            login_user(User(username))
            return redirect(url_for('dashboard'))
        return render_template('login.html', error="Invalid credentials")
    return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)
  1. Create templates/login.html:
html
<!DOCTYPE html>
<html>
<head><title>Login</title></head>
<body>
    <h1>Login</h1>
    {% if error %}
        <p style="color: red;">{{ error }}</p>
    {% endif %}
    <form method="POST">
        <label>Username: <input type="text" name="username"></label><br>
        <label>Password: <input type="password" name="password"></label><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>
  1. Create templates/dashboard.html:
html
<!DOCTYPE html>
<html>
<head><title>Dashboard</title></head>
<body>
    <h1>Welcome to the Dashboard</h1>
    <a href="{{ url_for('logout') }}">Logout</a>
</body>
</html>
Django Login App:
  1. Update blog/views.py and urls.py as shown above.
  2. Create blog/templates/login.html:
html
<!DOCTYPE html>
<html>
<head><title>Login</title></head>
<body>
    <h1>Login</h1>
    {% if error %}
        <p style="color: red;">{{ error }}</p>
    {% endif %}
    <form method="POST">
        {% csrf_token %}
        <label>Username: <input type="text" name="username"></label><br>
        <label>Password: <input type="password" name="password"></label><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>
  1. Create blog/templates/dashboard.html:
html
<!DOCTYPE html>
<html>
<head><title>Dashboard</title></head>
<body>
    <h1>Welcome to the Dashboard</h1>
    <a href="{% url 'logout' %}">Logout</a>
</body>
</html>
  1. Create a superuser: python manage.py createsuperuser
  2. Run: python manage.py runserver
Output: Both apps provide a login system with a dashboard, accessible only to authenticated users.This example demonstrates authentication and session management in Flask and Django.
6. Deployment Basics (Heroku, PythonAnywhere)Preparing Apps for Deployment
  • Flask: Use gunicorn as a WSGI server and create a Procfile.
  • Django: Configure settings.py for production (e.g., DEBUG=False).
  • Dependencies: List in requirements.txt.
Flask Example:
  1. Create requirements.txt:
bash
pip freeze > requirements.txt
  1. Create Procfile:
web: gunicorn app:app
Django Example: Update settings.py:
python
DEBUG = False
ALLOWED_HOSTS = ['your-app-name.herokuapp.com', 'localhost']
Deploying to Heroku
  1. Install Heroku CLI: heroku.com
  2. Log in: heroku login
  3. Create app: heroku create your-app-name
  4. Deploy:
bash
git init
git add .
git commit -m "Initial commit"
heroku git:remote -a your-app-name
git push heroku main
Deploying to PythonAnywhere
  1. Sign up at pythonanywhere.com.
  2. Upload files via the dashboard.
  3. Configure WSGI file and reload the app.
Pros, Cons, and AlternativesPros:
  • Heroku: Easy deployment, scalable.
  • PythonAnywhere: Python-focused, beginner-friendly.
  • Both support custom domains and SSL.
Cons:
  • Heroku: Limited free tier, can be expensive.
  • PythonAnywhere: Limited control over server settings.
  • Both require learning platform-specific configurations.
Alternatives:
  • AWS Elastic Beanstalk: For advanced control.
  • Vercel: For modern, serverless deployments.
  • DigitalOcean: For custom server setups.
Best Practices:
  • Set DEBUG=False in production.
  • Use environment variables for sensitive data (e.g., SECRET_KEY).
  • Test deployments locally first.
  • Monitor logs for errors post-deployment.
Example: Deploying a Flask and Django AppFlask Deployment (Heroku):
  1. Update app.py with environment port:
python
import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, Flask!"

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)
  1. Create requirements.txt:
Flask==2.0.1
gunicorn==20.1.0
  1. Create Procfile:
web: gunicorn app:app
  1. Deploy:
bash
heroku create my-flask-app
git push heroku main
Django Deployment (PythonAnywhere):
  1. Upload project files via PythonAnywhere dashboard.
  2. Update settings.py:
python
DEBUG = False
ALLOWED_HOSTS = ['your-username.pythonanywhere.com']
  1. Configure WSGI file in PythonAnywhere dashboard.
  2. Reload the web app.
Output: Both apps are accessible online at their respective URLs.This example demonstrates deploying Flask and Django apps to production, ensuring accessibility and scalability.
7. Conclusion & Next StepsCongratulations on mastering Module 9! You’ve learned to build web applications with Flask and Django, covering routes, templates, forms, models, ORM, REST APIs, authentication, sessions, and deployment. These skills enable you to create modern web apps like blogs, task managers, and APIs.Next Steps:
  • Practice: Enhance the blog or task API (e.g., add more features).
  • Explore: Dive into FastAPI or advanced Django features.
  • Advance: Move to Module 10, covering testing and automation.
  • Resources:

0 comments:

Featured Post

Master Angular 20 Basics: A Complete Beginner’s Guide with Examples and Best Practices

Welcome to the complete Angular 20 learning roadmap ! This series takes you step by step from basics to intermediate concepts , with hands...

Subscribe

 
Toggle Footer
Top