A Django-based personal portfolio platform focused on a passwordless ("magic link") authentication experience, plus a collection of informational pages. Built with modern UX principles, clean animations, and comprehensive documentation.
- Overview
- Features
- Technology Stack
- Installation
- Configuration
- Usage
- Project Structure
- Development
- Security
- Future Development
- License
This repository powers a personal portfolio site built with Django. The core app owns public-facing pages (landing, about, projects), while the accounts app implements a passwordless login flow. Users register with an email address, receive verification links, and later sign in via one-time "magic" links that expire after use.
The project emphasizes:
- Clean UX: Smooth animations, loading states, and keyboard navigation
- Accessibility: ARIA labels, focus states, and semantic HTML
- Security: Rate limiting, token expiration, and secure token signing
- Code Quality: Comprehensive documentation, type hints, and error handling
- Passwordless auth: Email-based verification and login links that expire after first use
- Rate limiting: Built-in throttling on login (5 requests/15 min) and registration (3 requests/hour) to prevent abuse
- Async mail dispatch: Magic-link emails send in the background so requests stay fast
- Custom user model:
accounts.Useruses email as the primary identifier - Token security: Signed tokens with expiration and one-time use enforcement
- Modern UI: Dark theme with pastel accents and glassmorphism effects
- Smooth animations: Fade-in effects, hover transitions, and loading states
- Responsive design: Mobile-first approach with Tailwind CSS
- Accessibility: ARIA labels, keyboard navigation, and focus indicators
- Form validation: Client-side and server-side validation with clear error messages
- Comprehensive documentation: Docstrings for all functions and classes
- Type hints: Type annotations for better code clarity
- Error handling: Graceful error handling with user-friendly messages
- Code organization: Clear separation of concerns across apps
- Backend: Django 5.2.3
- Frontend: Tailwind CSS 3.4.13
- Database: SQLite (development)
- Email: SMTP (Gmail)
- Environment: python-dotenv
- Python 3.8+
- Node.js 14+ (for Tailwind CSS)
- npm or yarn
- Clone the repository:
git clone https://github.com/OhACD/website
cd website- Create a virtual environment and activate it:
# Windows
python -m venv .venv
.venv\Scripts\Activate.ps1
# Linux/Mac
python -m venv .venv
source .venv/bin/activate- Install Python dependencies:
cd my_website
pip install -r ../requirements.txt- Install Node dependencies:
cd ..
npm install- Build Tailwind CSS:
npm run tw:buildOr for development with watch mode:
npm run tw:watch- Apply migrations:
cd my_website
python manage.py migrate- Create a superuser (optional):
python manage.py createsuperuserCreate a .env file in the project root (or set environment variables):
# Django Settings
DJANGO_SECRET_KEY=your-secret-key-here
DJANGO_ALLOWED_HOSTS=127.0.0.1,localhost
DJANGO_DEBUG=True
DJANGO_CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8000,http://localhost:8000
# Email Configuration (Gmail)
EMAIL_HOST_USER=[email protected]
EMAIL_HOST_PASSWORD=your-app-specific-passwordFor Gmail, you'll need to:
- Enable 2-factor authentication
- Generate an app-specific password
- Use that password in
EMAIL_HOST_PASSWORD
cd my_website
python manage.py runserverAccess the site at:
- Landing page: http://127.0.0.1:8000/core/
- Admin panel: http://127.0.0.1:8000/admin/
- Accounts: http://127.0.0.1:8000/accounts/
-
Register: Visit
/accounts/register/and provide email/name- Receive verification email
- Click verification link to activate account
-
Login: Visit
/accounts/login/and provide email- Receive magic link email
- Click link to authenticate (one-time use)
-
Browse: Public pages at
/core/are accessible without authentication
- Registration: 3 attempts per hour per email
- Login: 5 requests per 15 minutes per email
website/
├── my_website/ # Django project root
│ ├── accounts/ # Authentication app
│ │ ├── models.py # User and MagicLink models
│ │ ├── views.py # Registration, login, verification views
│ │ ├── services.py # Email sending functions
│ │ ├── tokens.py # Token generation/verification
│ │ ├── rate_limit.py # Rate limiting logic
│ │ └── templates/ # Auth templates
│ ├── core/ # Public pages app
│ │ ├── views.py # Landing, about, projects views
│ │ └── templates/ # Public page templates
│ ├── main/ # Legacy app (may be removed)
│ └── my_website/ # Project settings
│ ├── settings.py # Django configuration
│ └── urls.py # URL routing
├── assets/ # Source CSS files
│ └── css/
│ └── input.css # Tailwind input
├── static/ # Compiled static files
│ └── css/
│ └── output.css # Tailwind output
├── requirements.txt # Python dependencies
├── package.json # Node dependencies
├── tailwind.config.js # Tailwind configuration
└── README.md # This file
- Follow PEP 8 for Python code
- Use type hints where appropriate
- Add docstrings to all functions and classes
- Keep functions focused and single-purpose
- New Pages: Add views in
core/views.pyand templates incore/templates/ - Auth Changes: Modify
accounts/app files - Styling: Update Tailwind classes or add custom CSS in
layout.html
Run Django tests:
cd my_website
python manage.py test- Set
DJANGO_DEBUG=Falsein environment - Update
ALLOWED_HOSTSwith production domain - Use a production database (PostgreSQL recommended)
- Configure proper email backend
- Set up static file serving (WhiteNoise or CDN)
- Build Tailwind CSS:
npm run tw:build
- CSRF Protection: Enabled via Django middleware
- Rate Limiting: Prevents abuse of email endpoints
- Token Security: Signed tokens with expiration
- One-Time Tokens: Magic links expire after use
- Input Validation: Email and name validation
- SQL Injection Protection: Django ORM prevents SQL injection
- XSS Protection: Django templates auto-escape
- Never commit
.envfiles - Use strong
SECRET_KEYin production - Enable HTTPS in production
- Regularly update dependencies
- Monitor rate limit violations
- HTML email templates for better email UX
- Background task queue (Celery) for email delivery
- Dynamic project data from GitHub API
- User profile pages
- Blog/content management system
- Analytics integration
- Dark/light theme toggle
- Internationalization (i18n)
- Add unit tests for all views
- Add integration tests for auth flow
- Performance optimization (caching, database queries)
- Add API endpoints
- Docker containerization
- CI/CD pipeline improvements
This project is open-source and available under the MIT License.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
- Email: [email protected]
- GitHub: OhACD
Built with Django, Tailwind CSS, and a focus on clean, maintainable code.