Creating an advanced-level Traffic Management System project using Flask and Bootstrap 5 involves designing a robust database structure, implementing Flask routes, and creating responsive and interactive web pages. Below is a detailed guide:
1. Database Structure
The database will store users, traffic signals, traffic cameras, traffic incidents, and other related data. We'll use SQLAlchemy (an ORM for Flask) to manage the database.
Database Models
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(200), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
traffic_signals = db.relationship('TrafficSignal', backref='user', lazy=True)
traffic_cameras = db.relationship('TrafficCamera', backref='user', lazy=True)
traffic_incidents = db.relationship('TrafficIncident', backref='user', lazy=True)
class TrafficSignal(db.Model):
id = db.Column(db.Integer, primary_key=True)
location = db.Column(db.String(100), nullable=False)
status = db.Column(db.String(50), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
traffic_incidents = db.relationship('TrafficIncident', backref='traffic_signal', lazy=True)
class TrafficCamera(db.Model):
id = db.Column(db.Integer, primary_key=True)
location = db.Column(db.String(100), nullable=False)
status = db.Column(db.String(50), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
traffic_incidents = db.relationship('TrafficIncident', backref='traffic_camera', lazy=True)
class TrafficIncident(db.Model):
id = db.Column(db.Integer, primary_key=True)
location = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
traffic_signal_id = db.Column(db.Integer, db.ForeignKey('traffic_signal.id'), nullable=False)
traffic_camera_id = db.Column(db.Integer, db.ForeignKey('traffic_camera.id'), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
2. Flask Application Structure
Organize the project into the following structure:
traffic_management_system/
│
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── routes/
│ │ ├── auth.py
│ │ ├── traffic_signals.py
│ │ ├── traffic_cameras.py
│ │ ├── traffic_incidents.py
│ │ └── main.py
│ ├── templates/
│ │ ├── base.html
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── register.html
│ │ ├── dashboard.html
│ │ ├── add_traffic_signal.html
│ │ ├── view_traffic_signals.html
│ │ ├── add_traffic_camera.html
│ │ ├── view_traffic_cameras.html
│ │ ├── add_traffic_incident.html
│ │ ├── view_traffic_incidents.html
│ │ └── view_traffic_incident_details.html
│ ├── static/
│ │ ├── css/
│ │ │ └── styles.css
│ │ └── js/
│ │ └── scripts.js
│ └── utils.py
│
├── config.py
├── requirements.txt
└── run.py
3. Flask Application Code
app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
db = SQLAlchemy()
login_manager = LoginManager()
def create_app():
app = Flask(__name__)
app.config.from_pyfile('config.py')
db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = 'auth.login'
from .routes.auth import auth_bp
from .routes.traffic_signals import traffic_signals_bp
from .routes.traffic_cameras import traffic_cameras_bp
from .routes.traffic_incidents import traffic_incidents_bp
from .routes.main import main_bp
app.register_blueprint(auth_bp)
app.register_blueprint(traffic_signals_bp)
app.register_blueprint(traffic_cameras_bp)
app.register_blueprint(traffic_incidents_bp)
app.register_blueprint(main_bp)
return app
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///' + os.path.join(basedir, 'traffic_management_system.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
4. Flask Routes
routes/auth.py
from flask import Blueprint, render_template, redirect, url_for, flash
from flask_login import login_user, logout_user, login_required, current_user
from .forms import LoginForm, RegistrationForm
from ..models import User, db
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data, password=form.password.data)
db.session.add(user)
db.session.commit()
flash('Registration successful! You can now log in.')
return redirect(url_for('auth.login'))
return render_template('register.html', form=form)
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and user.password == form.password.data: # Replace with hashed password check
login_user(user)
return redirect(url_for('main.dashboard'))
flash('Login failed. Check your email and password.')
return render_template('login.html', form=form)
@auth_bp.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('main.index'))
routes/traffic_signals.py
from flask import Blueprint, render_template, redirect, url_for, flash
from flask_login import login_required, current_user
from ..models import TrafficSignal, db
from ..forms import TrafficSignalForm
traffic_signals_bp = Blueprint('traffic_signals', __name__)
@traffic_signals_bp.route('/add_traffic_signal', methods=['GET', 'POST'])
@login_required
def add_traffic_signal():
form = TrafficSignalForm()
if form.validate_on_submit():
signal = TrafficSignal(location=form.location.data, status=form.status.data, user_id=current_user.id)
db.session.add(signal)
db.session.commit()
flash('Traffic signal added successfully!')
return redirect(url_for('traffic_signals.view_traffic_signals'))
return render_template('add_traffic_signal.html', form=form)
@traffic_signals_bp.route('/traffic_signals')
@login_required
def view_traffic_signals():
signals = TrafficSignal.query.all()
return render_template('view_traffic_signals.html', signals=signals)
routes/traffic_cameras.py
from flask import Blueprint, render_template, redirect, url_for, flash
from flask_login import login_required, current_user
from ..models import TrafficCamera, db
from ..forms import TrafficCameraForm
traffic_cameras_bp = Blueprint('traffic_cameras', __name__)
@traffic_cameras_bp.route('/add_traffic_camera', methods=['GET', 'POST'])
@login_required
def add_traffic_camera():
form = TrafficCameraForm()
if form.validate_on_submit():
camera = TrafficCamera(location=form.location.data, status=form.status.data, user_id=current_user.id)
db.session.add(camera)
db.session.commit()
flash('Traffic camera added successfully!')
return redirect(url_for('traffic_cameras.view_traffic_cameras'))
return render_template('add_traffic_camera.html', form=form)
@traffic_cameras_bp.route('/traffic_cameras')
@login_required
def view_traffic_cameras():
cameras = TrafficCamera.query.all()
return render_template('view_traffic_cameras.html', cameras=cameras)
routes/traffic_incidents.py
from flask import Blueprint, render_template, redirect, url_for, flash
from flask_login import login_required, current_user
from ..models import TrafficIncident, db
from ..forms import TrafficIncidentForm
traffic_incidents_bp = Blueprint('traffic_incidents', __name__)
@traffic_incidents_bp.route('/add_traffic_incident', methods=['GET', 'POST'])
@login_required
def add_traffic_incident():
form = TrafficIncidentForm()
if form.validate_on_submit():
incident = TrafficIncident(location=form.location.data, description=form.description.data,
user_id=current_user.id, traffic_signal_id=form.traffic_signal_id.data,
traffic_camera_id=form.traffic_camera_id.data)
db.session.add(incident)
db.session.commit()
flash('Traffic incident reported successfully!')
return redirect(url_for('traffic_incidents.view_traffic_incidents'))
return render_template('add_traffic_incident.html', form=form)
@traffic_incidents_bp.route('/traffic_incidents')
@login_required
def view_traffic_incidents():
incidents = TrafficIncident.query.all()
return render_template('view_traffic_incidents.html', incidents=incidents)
@traffic_incidents_bp.route('/incident/<int:incident_id>')
@login_required
def view_incident_details(incident_id):
incident = TrafficIncident.query.get_or_404(incident_id)
return render_template('view_traffic_incident_details.html', incident=incident)
5. HTML Templates with Bootstrap 5
templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
<title>{% block title %}Traffic Management System{% endblock %}</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="{{ url_for('main.index') }}">Traffic Management</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto">
{% if current_user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('main.dashboard') }}">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('traffic_signals.view_traffic_signals') }}">View Traffic Signals</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('traffic_cameras.view_traffic_cameras') }}">View Traffic Cameras</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('traffic_incidents.view_traffic_incidents') }}">View Traffic Incidents</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.logout') }}">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.login') }}">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.register') }}">Register</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<div class="container mt-4">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-info">
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
templates/index.html
{% extends 'base.html' %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome to the Traffic Management System</h1>
<p>Manage traffic signals, cameras, and incidents efficiently!</p>
{% endblock %}
templates/dashboard.html
{% extends 'base.html' %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<h2>Dashboard</h2>
<p>Welcome, {{ current_user.username }}!</p>
{% endblock %}
templates/add_traffic_signal.html
{% extends 'base.html' %}
{% block title %}Add Traffic Signal{% endblock %}
{% block content %}
<h2>Add Traffic Signal</h2>
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.location.label(class="form-label") }}
{{ form.location(class="form-control") }}
</div>
<div class="mb-3">
{{ form.status.label(class="form-label") }}
{{ form.status(class="form-control") }}
</div>
<button type="submit" class="btn btn-primary">Add Traffic Signal</button>
</form>
{% endblock %}
templates/view_traffic_signals.html
{% extends 'base.html' %}
{% block title %}View Traffic Signals{% endblock %}
{% block content %}
<h2>Traffic Signals</h2>
<table class="table">
<thead>
<tr>
<th scope="col">Location</th>
<th scope="col">Status</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for signal in signals %}
<tr>
<td>{{ signal.location }}</td>
<td>{{ signal.status }}</td>
<td>
<a href="{{ url_for('traffic_incidents.add_traffic_incident', signal_id=signal.id) }}" class="btn btn-secondary">Report Incident</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
templates/add_traffic_camera.html
{% extends 'base.html' %}
{% block title %}Add Traffic Camera{% endblock %}
{% block content %}
<h2>Add Traffic Camera</h2>
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.location.label(class="form-label") }}
{{ form.location(class="form-control") }}
</div>
<div class="mb-3">
{{ form.status.label(class="form-label") }}
{{ form.status(class="form-control") }}
</div>
<button type="submit" class="btn btn-primary">Add Traffic Camera</button>
</form>
{% endblock %}
templates/view_traffic_cameras.html
{% extends 'base.html' %}
{% block title %}View Traffic Cameras{% endblock %}
{% block content %}
<h2>Traffic Cameras</h2>
<table class="table">
<thead>
<tr>
<th scope="col">Location</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
{% for camera in cameras %}
<tr>
<td>{{ camera.location }}</td>
<td>{{ camera.status }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
templates/add_traffic_incident.html
{% extends 'base.html' %}
{% block title %}Add Traffic Incident{% endblock %}
{% block content %}
<h2>Add Traffic Incident</h2>
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.location.label(class="form-label") }}
{{ form.location(class="form-control") }}
</div>
<div class="mb-3">
{{ form.description.label(class="form-label") }}
{{ form.description(class="form-control") }}
</div>
<div class="mb-3">
{{ form.traffic_signal_id.label(class="form-label") }}
{{ form.traffic_signal_id(class="form-control") }}
</div>
<div class="mb-3">
{{ form.traffic_camera_id.label(class="form-label") }}
{{ form.traffic_camera_id(class="form-control") }}
</div>
<button type="submit" class="btn btn-primary">Report Incident</button>
</form>
{% endblock %}
templates/view_traffic_incident_details.html
{% extends 'base.html' %}
{% block title %}Traffic Incident Details{% endblock %}
{% block content %}
<h2>Incident Details</h2>
<p><strong>Location:</strong> {{ incident.location }}</p>
<p><strong>Description:</strong> {{ incident.description }}</p>
<p><strong>Reported By:</strong> {{ incident.user.username }}</p>
<p><strong>Traffic Signal:</strong> {{ incident.traffic_signal.location if incident.traffic_signal else 'N/A' }}</p>
<p><strong>Traffic Camera:</strong> {{ incident.traffic_camera.location if incident.traffic_camera else 'N/A' }}</p>
<p><strong>Reported At:</strong> {{ incident.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</p>
<a href="{{ url_for('traffic_incidents.view_traffic_incidents') }}" class="btn btn-secondary">Back to Incidents</a>
{% endblock %}
6. Forms for Flask-WTF
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SelectField, SubmitField
from wtforms.validators import DataRequired, Length
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=50)])
email = StringField('Email', validators=[DataRequired(), Length(max=100)])
password = StringField('Password', validators=[DataRequired(), Length(min=6, max=200)])
submit = SubmitField('Register')
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired()])
password = StringField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
class TrafficSignalForm(FlaskForm):
location = StringField('Location', validators=[DataRequired()])
status = StringField('Status', validators=[DataRequired()])
submit = SubmitField('Add Traffic Signal')
class TrafficCameraForm(FlaskForm):
location = StringField('Location', validators=[DataRequired()])
status = StringField('Status', validators=[DataRequired()])
submit = SubmitField('Add Traffic Camera')
class TrafficIncidentForm(FlaskForm):
location = StringField('Location', validators=[DataRequired()])
description = TextAreaField('Description', validators=[DataRequired()])
traffic_signal_id = SelectField('Traffic Signal', coerce=int, validators=[DataRequired()])
traffic_camera_id = SelectField('Traffic Camera', coerce=int, validators=[DataRequired()])
submit = SubmitField('Report Incident')
7. Static Files
static/css/styles.css
body {
background-color: #f8f9fa;
}
.navbar {
margin-bottom: 20px;
}
.table {
margin-top: 20px;
}
8. JavaScript (if needed)
static/js/scripts.js
// Custom JavaScript can be added here
9. Running the Application
To run the application, ensure you have the required packages installed as specified in requirements.txt, then execute:
python run.py
This structure and code provide a comprehensive foundation for an advanced Traffic Management System project using Flask and Bootstrap 5, allowing for user management, traffic signal and camera management, and incident reporting. The application is designed to be scalable and maintainable, with a clear separation of concerns between models, routes, and templates.