A powerful Django SEO optimization package that helps you manage and optimize your website's SEO with modern Python features and best practices.
- 🚀 Modern Python (3.8+) & Django (3.2+) compatibility
- 🎯 Smart metadata management with multiple backend support
- 🌐 Advanced site-specific SEO optimization
- 🔄 Intelligent redirect management with pattern matching
- 🎨 Dynamic template support in metadata
- ⚡ Performance-optimized with async support and caching
- 🔍 Advanced URL pattern matching and routing
- 🌍 Comprehensive i18n/l10n support
- 🔒 Type hints and modern Python features
- 📊 SEO performance analytics and reporting
- 🤖 Automated meta tag optimization
- 🔗 Sitemap generation and management
- 📱 Mobile SEO optimization support
pip install django-seo-optimizer
- Add 'seo_optimizer' to your INSTALLED_APPS:
INSTALLED_APPS = [
...
'seo_optimizer',
]
- Run migrations:
python manage.py migrate seo_optimizer
- Configure your SEO metadata:
from seo_optimizer import register_metadata, MetadataField
@register_metadata
class MyMetadata:
title = MetadataField(max_length=70)
description = MetadataField(max_length=160)
keywords = KeywordsField()
robots = RobotsField()
- Use in your templates:
{% load seo_tags %}
{% get_metadata as meta %}
<title>{{ meta.title }}</title>
<meta name="description" content="{{ meta.description }}">
<meta name="keywords" content="{{ meta.keywords }}">
<meta name="robots" content="{{ meta.robots }}">
from seo_optimizer.async_utils import AsyncMetadataManager
async def get_optimized_metadata(path):
manager = AsyncMetadataManager()
metadata = await manager.get_metadata(path)
return metadata
from seo_optimizer.models import RedirectPattern
RedirectPattern.objects.create(
url_pattern="/old-blog/*",
redirect_url="/blog/$1",
is_regex=True,
status_code=301
)
from seo_optimizer.analytics import SEOAnalytics
analytics = SEOAnalytics()
report = analytics.generate_report()
print(report.suggestions)
The base field type for SEO metadata:
from seo_optimizer import MetadataField
title = MetadataField(
max_length=70,
required=True,
template_support=True
)
Parameters:
max_length
: Maximum length of the field valuerequired
: Whether the field is requiredtemplate_support
: Enable Django template syntax in field valuesvalidators
: List of validation functions
from seo_optimizer import KeywordsField, RobotsField, OpenGraphField
# Keywords with automatic comma separation
keywords = KeywordsField(max_keywords=10)
# Robots directives with validation
robots = RobotsField(default="index,follow")
# Open Graph metadata
og = OpenGraphField(
title_max_length=95,
description_max_length=200
)
For high-performance async metadata operations:
from seo_optimizer import AsyncMetadataManager
async def get_meta(path):
manager = AsyncMetadataManager()
return await manager.get_metadata(path)
Available settings in settings.py
:
SEO_OPTIMIZER = {
'CACHE_TIMEOUT': 3600, # 1 hour
'ASYNC_ENABLED': True,
'MAX_ASYNC_WORKERS': 10,
'USE_SITES_FRAMEWORK': True,
'DEFAULT_LANGUAGE': 'en',
}
- Install the package:
pip install django-seo-optimizer
- Add to INSTALLED_APPS:
INSTALLED_APPS = [
...
'seo_optimizer',
]
- Run migrations:
python manage.py migrate seo_optimizer
Create a metadata configuration file (e.g., seo.py
):
from seo_optimizer import register_metadata, MetadataField
@register_metadata
class BlogMetadata:
title = MetadataField(max_length=70)
description = MetadataField(max_length=160)
keywords = KeywordsField()
class Meta:
use_cache = True
use_sites = True
use_i18n = True
{% load seo_tags %}
{% get_metadata as meta %}
<head>
<title>{{ meta.title }}</title>
<meta name="description" content="{{ meta.description }}">
<meta name="keywords" content="{{ meta.keywords }}">
{% if meta.og %}
<meta property="og:title" content="{{ meta.og.title }}">
<meta property="og:description" content="{{ meta.og.description }}">
{% endif %}
</head>
@register_metadata
class ProductMetadata:
title = MetadataField(
template="{{product.name}} - Buy Online | {{site.name}}"
)
description = MetadataField(
template="Shop {{product.name}} starting at ${{product.price}}. {{product.short_description}}"
)
def get_context(self, request):
return {
'product': Product.objects.get(slug=request.path.split('/')[-1])
}
@register_metadata
class I18nMetadata:
title = MetadataField()
description = MetadataField()
class Meta:
use_i18n = True
def get_translations(self, language):
return {
'title': {
'en': 'Welcome to our store',
'es': 'Bienvenido a nuestra tienda'
},
'description': {
'en': 'Shop the best products online',
'es': 'Compra los mejores productos en línea'
}
}
from seo_optimizer.models import RedirectPattern
# Redirect old blog URLs to new structure
RedirectPattern.objects.create(
url_pattern="/blog/(\d{4})/(\d{2})/(.+)",
redirect_url="/articles/$3",
is_regex=True,
status_code=301
)
-
Enable Caching:
class Meta: use_cache = True cache_timeout = 3600 # 1 hour
-
Use Async Support for high-traffic pages:
async def get_product_meta(request): return await ProductMetadata.async_get_metadata(request.path)
-
Batch Process metadata updates:
from seo_optimizer.utils import bulk_metadata_update await bulk_metadata_update(ProductMetadata, products)
- Title Length: Keep titles between 50-60 characters
- Description Length: Aim for 150-160 characters
- Keywords: Use 5-8 relevant keywords
- Mobile Optimization: Enable mobile-specific metadata
- URL Structure: Use clean, descriptive URLs
- Sitemap: Generate and update regularly
-
Sanitize User Input:
from seo_optimizer.utils import sanitize_meta title = sanitize_meta(user_input)
-
API Keys: Store sensitive data in environment variables
-
Rate Limiting: Enable for metadata API endpoints
-
Access Control: Restrict admin interface access
-
Enable Analytics:
SEO_OPTIMIZER = { 'ENABLE_ANALYTICS': True, 'ANALYTICS_RETENTION': 90 # days }
-
Track Performance:
from seo_optimizer.analytics import track_meta_performance performance_data = await track_meta_performance('/products/')
-
Set Up Alerts for SEO issues and errors
We love your input! We want to make contributing to Django SEO Optimizer as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer
- Fork the repo and create your branch from
develop
- Install development dependencies:
pip install -e ".[dev]"
- Make your changes and add tests
- Run tests and ensure they pass:
pytest pytest --cov=seo_optimizer # with coverage
- Update documentation if needed
- Submit a pull request
We use several tools to maintain code quality:
# Format code
black seo_optimizer
# Sort imports
isort seo_optimizer
# Check types
mypy seo_optimizer
# Run linter
flake8 seo_optimizer
Follow these guidelines:
- Use the present tense ("Add feature" not "Added feature")
- Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
- Limit the first line to 72 characters
- Reference issues and pull requests after the first line
For more detailed information about contributing, please see our Contributing Guide.
For detailed documentation, visit avixiii.com/django-seo-optimizer
This project is licensed under the MIT License - see the LICENSE file for details.
Created and maintained by avixiii.
- Documentation: avixiii.com/django-seo-optimizer
- Source Code: github.com/avixiii-dev/django-seo-optimizer
- Issue Tracker: github.com/avixiii-dev/django-seo-optimizer/issues