A production-grade reusable Django comments app with REST API, moderation, spam detection, and GDPR compliance
Project description
Django Reusable Comments
A production-grade, feature-complete Django app for adding sophisticated comment functionality to any model. Built with performance optimization, extensive customization options, email notifications, content formatting, spam detection, GDPR compliance, and full REST API support.
โก What's New in v1.0
- ๐ง 8 Email Notification Types - Beautiful HTML templates with async threading support (no broker needed)
- ๐จ Content Formatting - Plain text, Markdown, and HTML with XSS protection
- ๐ก๏ธ Advanced Spam Detection - ML-ready with custom detector callbacks
- โฑ๏ธ 3-Tier Rate Limiting - DRF integration with user/anon/burst protection
- ๐ Smart Pagination - Thread-aware pagination for nested comments
- ๐ Enhanced Security - XSS protection, HTML sanitization, profanity filtering
- ๐ค Auto-Moderation - Threshold-based auto-hide, auto-delete, auto-ban
- ๐ซ Ban System - Auto-ban after spam flags or rejections, temporary/permanent bans
- โ๏ธ Comment Editing - Time-windowed editing with full revision history
- โ๏ธ GDPR Compliance - Data export, deletion, anonymization, retention policies
- โ๏ธ 60+ Settings - Complete configurability for every aspect
๐ Features
Core Features
- โ Model Agnostic - Add comments to any Django model
- โ ID Flexibility - Support for both UUID and integer primary keys
- โ Threaded Comments - Nested replies with configurable depth limits
- โ Performance Optimized - Advanced caching, query optimization, select_related
- โ REST API - Complete DRF integration with filtering, search, ordering
- โ Admin Interface - Feature-rich admin with bulk actions and optimized queries
Content & Formatting
- ๐จ Multiple Formats
- Plain text (HTML escaped - safest)
- Markdown (with CommonMark extensions)
- HTML (sanitized with bleach)
- ๐ XSS Protection - Automatic HTML sanitization
- ๐ Profanity Filtering - Censor, flag, hide, or delete
- โ๏ธ Comment Editing - Configurable time windows
- ๐ Edit History - Complete revision tracking
Spam & Content Control
- ๐ก๏ธ Spam Detection
- Word-based detection
- Custom ML detector callbacks
- Configurable actions (flag/hide/delete)
- ๐จ Auto-Moderation
- Auto-hide after N flags
- Auto-delete after N flags
- Auto-ban spammers
- ๐ซ Flag System
- Spam, inappropriate, harassment flags
- Abuse prevention (rate limits)
- Moderator notifications
Moderation & Workflows
- ๐ฎ Moderation Queue
- Approve/reject workflow
- Group-based permissions
- Auto-approval for trusted users
- ๐จ Ban System
- Auto-ban after rejections/spam flags
- Temporary or permanent bans
- Ban notifications
- ๐ Moderation Logs
- Complete audit trail
- 90-day default retention
- All actions logged
Notifications
-
๐ง 8 Notification Types
- New comment notifications
- Reply notifications
- Approval notifications
- Rejection notifications
- Moderator alerts (non-public comments)
- User ban notifications
- User unban notifications
- Flag threshold notifications
-
โก Async Support
- Built-in threading (no broker or external service needed)
- Fire-and-forget daemon threads; failures logged
- Beautiful HTML email templates
API Features
-
โฑ๏ธ Rate Limiting
- User limits (default: 100/day)
- Anonymous limits (default: 20/day)
- Burst protection (default: 5/min)
- DRF throttling integration
-
๐ Pagination
- Standard pagination
- Thread-aware pagination
- Configurable page sizes
- Client-controlled page size
-
๐ Advanced Filtering
- Filter by user, content object, public status
- Full-text search
- Date range filtering
- Custom ordering
GDPR Compliance
-
โ๏ธ Data Subject Rights
- Right to data portability (export)
- Right to erasure (deletion)
- Right to be forgotten (anonymization)
-
๐ Privacy Controls
- Optional IP address collection
- Optional user agent collection
- Auto-anonymize on user deletion
- Retention policy automation
-
๐ Data Management
- Export all user data as JSON
- Anonymize old comments automatically
- Management commands for compliance
Developer Experience
- โ Signals - Robust signal system for extending functionality
- ๐ Internationalization - Full i18n support using gettext_lazy
- ๐ท๏ธ Template Tags - Convenient template tags with caching
- ๐งช Testing - Comprehensive test suite (280+ tests)
- ๐ Documentation - Thorough documentation for developers
- ๐ชต Logging - Sophisticated error handling and logging
๐ฏ Choosing Your API Pattern
| Pattern | Best For | Security Model |
|---|---|---|
Generic (/api/comments/) |
Admin dashboards, backend services, bulk operations | Standard DRF permissions |
Object-Specific (/api/{app}/{model}/{id}/comments/) |
Public frontends, mobile apps, untrusted clients | Zero-trust (backend-controlled metadata) |
Both patterns are fully supported. Use object-specific for enhanced security in public-facing applications.
๐ฆ Installation
Quick Install
# Install the package
pip install django-reusable-comments
# Install optional dependencies
pip install markdown bleach # For formatting support
pip install markdown # For Markdown formatting (optional)
Add to INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
# Django apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites', # Required for email notifications
# Third-party apps
'rest_framework',
'django_filters',
# Django comments
'django_comments',
# Your apps
# ...
]
SITE_ID = 1 # Required for email notifications
Run Migrations
python manage.py migrate django_comments
Include URL Patterns
# urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/comments/', include('django_comments.urls')),
# Your URLs
]
โก Quick Start
Django Reusable Comments provides two API patterns:
Option 1: Generic Endpoint (Admin/Backend Use)
// List comments
const response = await fetch('/api/comments/?content_type=blog.post&object_id=123');
const comments = await response.json();
// Create comment
await fetch('/api/comments/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token YOUR_TOKEN'
},
body: JSON.stringify({
content_type: 'blog.post',
object_id: '123',
content: 'Great article!'
})
});
Option 2: Object-Specific Endpoint (Public Frontends - Recommended)
// List comments for a specific object
const response = await fetch('/api/blog/post/123/comments/');
const comments = await response.json();
// Create comment (backend controls metadata)
await fetch('/api/blog/post/123/comments/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token YOUR_TOKEN'
},
body: JSON.stringify({
content: 'Great article!' // Only content needed!
})
});
๐ Security Note: The object-specific endpoint (/api/{app_label}/{model}/{object_id}/comments/) is recommended for public-facing applications as it prevents users from manipulating metadata like content_type or object_id.
โ๏ธ Configuration
Minimal Configuration
# settings.py
DJANGO_COMMENTS_CONFIG = {
# Required: Specify which models can receive comments
'COMMENTABLE_MODELS': [
'blog.Post',
'products.Product',
],
}
Basic Configuration
# settings.py
DJANGO_COMMENTS_CONFIG = {
# Models that can receive comments
'COMMENTABLE_MODELS': ['blog.Post', 'products.Product'],
# Enable features
'SEND_NOTIFICATIONS': True,
'COMMENT_FORMAT': 'markdown', # 'plain', 'markdown', or 'html'
'ALLOW_ANONYMOUS': False,
# Moderation
'MODERATOR_REQUIRED': True,
'AUTO_APPROVE_GROUPS': ['Moderators', 'Staff'],
'AUTO_APPROVE_AFTER_N_APPROVED': 5,
# Threading
'MAX_COMMENT_DEPTH': 3,
# API Rate Limiting
'API_RATE_LIMIT': '100/day',
'API_RATE_LIMIT_ANON': '20/day',
'API_RATE_LIMIT_BURST': '5/min',
}
Production Configuration
# settings.py
DJANGO_COMMENTS_CONFIG = {
# Models
'COMMENTABLE_MODELS': ['blog.Post', 'products.Product', 'news.Article'],
# Content
'MAX_COMMENT_LENGTH': 3000,
'ALLOW_ANONYMOUS': False,
'COMMENT_FORMAT': 'markdown',
'MAX_COMMENT_DEPTH': 3,
# Moderation
'MODERATOR_REQUIRED': True,
'AUTO_APPROVE_GROUPS': ['Moderators', 'Staff'],
'AUTO_APPROVE_AFTER_N_APPROVED': 5,
'TRUSTED_USER_GROUPS': ['Premium', 'Verified'],
# Spam Detection
'SPAM_DETECTION_ENABLED': True,
'SPAM_DETECTOR': 'myapp.ml.detect_spam', # Custom ML detector
'SPAM_ACTION': 'flag',
# Profanity Filtering
'PROFANITY_FILTERING': True,
'PROFANITY_LIST': ['badword1', 'badword2'],
'PROFANITY_ACTION': 'censor',
# Auto-Moderation
'AUTO_HIDE_THRESHOLD': 3,
'AUTO_DELETE_THRESHOLD': 10,
'FLAG_NOTIFICATION_THRESHOLD': 1,
'AUTO_HIDE_DETECTED_SPAM': True,
# Ban System
'AUTO_BAN_AFTER_REJECTIONS': 5,
'AUTO_BAN_AFTER_SPAM_FLAGS': 3,
'DEFAULT_BAN_DURATION_DAYS': 30,
# Notifications
'SEND_NOTIFICATIONS': True,
'USE_ASYNC_NOTIFICATIONS': True, # Uses built-in threading (no broker needed)
'NOTIFY_ON_FLAG': True,
'NOTIFY_ON_AUTO_HIDE': True,
# API
'API_RATE_LIMIT': '100/day',
'API_RATE_LIMIT_ANON': '20/day',
'API_RATE_LIMIT_BURST': '5/min',
'PAGE_SIZE': 20,
'MAX_PAGE_SIZE': 100,
# Editing
'ALLOW_COMMENT_EDITING': True,
'EDIT_TIME_WINDOW': 3600, # 1 hour
'TRACK_EDIT_HISTORY': True,
# GDPR
'GDPR_ENABLED': True,
'GDPR_ALLOW_USER_DATA_EXPORT': True,
'GDPR_ALLOW_USER_DATA_DELETION': True,
'GDPR_ANONYMIZE_ON_USER_DELETE': True,
'GDPR_ENABLE_RETENTION_POLICY': True,
'GDPR_RETENTION_DAYS': 365,
# Caching
'CACHE_TIMEOUT': 3600,
# Logging
'LOGGER_NAME': 'django_comments',
}
For complete configuration reference, see configuration.md.
๐ง Email Notifications
Setup
# settings.py
DJANGO_COMMENTS_CONFIG = {
'SEND_NOTIFICATIONS': True,
'DEFAULT_FROM_EMAIL': 'noreply@yourdomain.com',
'COMMENT_NOTIFICATION_EMAILS': ['moderators@yourdomain.com'],
}
# Configure Django email backend
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'
EMAIL_HOST_PASSWORD = 'your-password'
Async Notifications (Built-in Threading)
# settings.py
DJANGO_COMMENTS_CONFIG = {
'SEND_NOTIFICATIONS': True,
'USE_ASYNC_NOTIFICATIONS': True, # dispatches in a daemon Thread
}
# No Celery or Redis needed โ works out of the box.
Custom Email Templates
DJANGO_COMMENTS_CONFIG = {
'NOTIFICATION_EMAIL_TEMPLATE': 'myapp/emails/new_comment.html',
'NOTIFICATION_REPLY_TEMPLATE': 'myapp/emails/comment_reply.html',
'NOTIFICATION_APPROVED_TEMPLATE': 'myapp/emails/approved.html',
'NOTIFICATION_REJECTED_TEMPLATE': 'myapp/emails/rejected.html',
'NOTIFICATION_MODERATOR_TEMPLATE': 'myapp/emails/moderator_alert.html',
'NOTIFICATION_USER_BAN_TEMPLATE': 'myapp/emails/banned.html',
'NOTIFICATION_USER_UNBAN_TEMPLATE': 'myapp/emails/unbanned.html',
'NOTIFICATION_FLAG_TEMPLATE': 'myapp/emails/flag_alert.html',
}
๐ค Custom Spam Detection
Simple Word-Based Detection
DJANGO_COMMENTS_CONFIG = {
'SPAM_DETECTION_ENABLED': True,
'SPAM_WORDS': [
'viagra', 'casino', 'lottery', 'prize',
'click here', 'buy now', 'limited time'
],
'SPAM_ACTION': 'flag',
}
Custom ML-Based Detection
# myapp/spam.py
import joblib
# Load your trained model
model = joblib.load('path/to/spam_model.pkl')
vectorizer = joblib.load('path/to/vectorizer.pkl')
def detect_spam(content):
"""
Custom spam detection using ML model.
Args:
content (str): Comment content to check
Returns:
tuple: (is_spam: bool, reason: str)
"""
# Vectorize and predict
features = vectorizer.transform([content])
prediction = model.predict(features)[0]
probability = model.predict_proba(features)[0][1]
if prediction == 1: # Spam
return True, f"Spam detected (confidence: {probability:.2%})"
return False, None
# settings.py
DJANGO_COMMENTS_CONFIG = {
'SPAM_DETECTION_ENABLED': True,
'SPAM_DETECTOR': 'myapp.spam.detect_spam',
'SPAM_ACTION': 'hide', # Auto-hide detected spam
}
๐ซ Auto-Moderation System
Flag-Based Auto-Moderation
DJANGO_COMMENTS_CONFIG = {
# Hide comment after 3 user flags
'AUTO_HIDE_THRESHOLD': 3,
# Delete comment after 10 user flags
'AUTO_DELETE_THRESHOLD': 10,
# Notify moderators at first flag
'FLAG_NOTIFICATION_THRESHOLD': 1,
# Auto-hide detected spam immediately
'AUTO_HIDE_DETECTED_SPAM': True,
}
Auto-Ban System
DJANGO_COMMENTS_CONFIG = {
# Ban user after 5 rejected comments
'AUTO_BAN_AFTER_REJECTIONS': 5,
# Ban user after 3 spam flags across all their comments
'AUTO_BAN_AFTER_SPAM_FLAGS': 3,
# Default ban duration (None = permanent)
'DEFAULT_BAN_DURATION_DAYS': 30,
}
How Auto-Ban Works:
- User posts spammy content
- Comments get flagged or rejected
- When thresholds reached โ User automatically banned
- Ban notification sent to user
- All future comment attempts blocked
โ๏ธ Comment Editing
Enable Editing
DJANGO_COMMENTS_CONFIG = {
# Allow users to edit their comments
'ALLOW_COMMENT_EDITING': True,
# 1 hour editing window
'EDIT_TIME_WINDOW': 3600,
# Track all edits
'TRACK_EDIT_HISTORY': True,
}
โ๏ธ GDPR Compliance
Enable GDPR Features
DJANGO_COMMENTS_CONFIG = {
'GDPR_ENABLED': True,
# User rights
'GDPR_ALLOW_USER_DATA_EXPORT': True,
'GDPR_ALLOW_USER_DATA_DELETION': True,
# Auto-anonymize when user account deleted
'GDPR_ANONYMIZE_ON_USER_DELETE': True,
# Retention policy
'GDPR_ENABLE_RETENTION_POLICY': True,
'GDPR_RETENTION_DAYS': 365,
# Privacy settings
'GDPR_COLLECT_IP_ADDRESS': True,
'GDPR_COLLECT_USER_AGENT': True,
'GDPR_ANONYMIZE_IP_ON_RETENTION': True,
}
Data Export
from django_comments.gdpr import export_user_data
# Export all user's comment data
data = export_user_data(user)
# Returns: {
# 'comments': [...],
# 'flags': [...],
# 'moderation_actions': [...],
# 'export_date': '2025-01-15T10:30:00Z'
# }
Data Deletion/Anonymization
from django_comments.gdpr import anonymize_user_data
# Anonymize all user's data
anonymize_user_data(user)
# Anonymizes: username, email, IP addresses, user agent
# Keeps: comment content (attributed to "Anonymous")
Management Commands
# Anonymize comments older than retention period
python manage.py anonymize_old_comments
# Schedule in cron
0 2 * * 0 python manage.py anonymize_old_comments # Weekly at 2 AM
๐ API Endpoints
Comments
# List comments
GET /api/comments/
GET /api/comments/?content_type=blog.post&object_id=123
GET /api/comments/?user=5&is_public=true
GET /api/comments/?search=keyword
GET /api/comments/?ordering=-created_at
# Create comment
POST /api/comments/
{
"content_type": "blog.post",
"object_id": "123",
"content": "Great article!",
"parent": null
}
# Get comment
GET /api/comments/{id}/
# Update comment
PATCH /api/comments/{id}/
{
"content": "Updated content"
}
# Delete comment
DELETE /api/comments/{id}/
# Approve comment (moderators only)
POST /api/comments/{id}/approve/
# Reject comment (moderators only)
POST /api/comments/{id}/reject/
# Flag comment
POST /api/comments/{id}/flag/
{
"flag": "spam", # or "inappropriate", "harassment"
"reason": "This is spam"
}
Flags
# List flags (moderators only)
GET /api/flags/
GET /api/flags/?comment={comment_id}
GET /api/flags/?user={user_id}
GET /api/flags/?flag=spam
# Review flag (moderators only)
POST /api/flags/{id}/review/
{
"action": "approve" # or "dismiss"
}
Banned Users
# List banned users (moderators only)
GET /api/banned-users/
GET /api/banned-users/?is_active=true
# Ban user (moderators only)
POST /api/banned-users/
{
"user": 5,
"reason": "Repeated spam",
"banned_until": "2025-02-15T00:00:00Z" # null for permanent
}
# Unban user (moderators only)
DELETE /api/banned-users/{id}/
Content Object Comments
# Get all comments for a specific object
GET /api/content-comments/
?content_type=blog.post
&object_id=123
&ordering=-created_at
๐ท๏ธ Template Tags
Load Template Tags
{% load comment_tags %}
Display Comments
{# Render comment form #}
{% render_comment_form for article %}
{# Display comment count #}
{% get_comment_count for article as comment_count %}
<p>{{ comment_count }} comments</p>
{# List comments #}
{% get_comments for article as comments %}
{% for comment in comments %}
<div class="comment">
<strong>{{ comment.user.username }}</strong>
<p>{{ comment.content }}</p>
<small>{{ comment.created_at }}</small>
</div>
{% endfor %}
{# Check if user can comment #}
{% can_comment user article as can_post %}
{% if can_post %}
<a href="{% url 'add_comment' %}">Add Comment</a>
{% endif %}
๐ Signals
Available Signals
from django_comments.signals import (
comment_created,
comment_updated,
comment_deleted,
comment_flagged,
comment_approved,
comment_rejected,
user_banned,
user_unbanned,
)
Example Usage
from django.dispatch import receiver
from django_comments.signals import comment_created, comment_flagged
@receiver(comment_created)
def notify_on_new_comment(sender, instance, **kwargs):
"""Send custom notification when comment is created."""
print(f"New comment: {instance.content}")
# Your custom logic here
@receiver(comment_flagged)
def handle_flagged_comment(sender, instance, flag, user, **kwargs):
"""Handle when comment is flagged."""
if flag == 'spam':
# Custom spam handling
pass
๐งช Testing
Run the comprehensive test suite:
# Run all tests
python manage.py test django_comments
# Run specific test modules
python manage.py test django_comments.tests.test_models
python manage.py test django_comments.tests.test_views
python manage.py test django_comments.tests.test_signals
# Run with coverage
pip install coverage
coverage run --source='django_comments' manage.py test django_comments
coverage report
Test Coverage:
- 280+ tests
- 95%+ code coverage
- All critical paths tested
- Edge cases covered
๐ Management Commands
Cleanup Comments
# Remove non-public comments older than CLEANUP_AFTER_DAYS
python manage.py cleanup_comments
# Dry run (show what would be deleted)
python manage.py cleanup_comments --dry-run
Anonymize Old Comments (GDPR)
# Anonymize personal data older than GDPR_RETENTION_DAYS
python manage.py anonymize_old_comments
# Dry run
python manage.py anonymize_old_comments --dry-run
Moderation Queue
# Show comments pending moderation
python manage.py show_moderation_queue
# Show specific status
python manage.py show_moderation_queue --status=flagged
๐ฏ Use Cases
Blog Comments
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published = models.DateTimeField(auto_now_add=True)
# settings.py
DJANGO_COMMENTS_CONFIG = {
'COMMENTABLE_MODELS': ['blog.Post'],
'COMMENT_FORMAT': 'markdown',
'ALLOW_ANONYMOUS': True,
'MODERATOR_REQUIRED': False,
}
Product Reviews
# models.py
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10, decimal_places=2)
# settings.py
DJANGO_COMMENTS_CONFIG = {
'COMMENTABLE_MODELS': ['products.Product'],
'MODERATOR_REQUIRED': True, # Review all product feedback
'ALLOW_ANONYMOUS': False, # Verified purchases only
'SEND_NOTIFICATIONS': True,
}
Community Forum
# settings.py
DJANGO_COMMENTS_CONFIG = {
'COMMENTABLE_MODELS': ['forum.Thread'],
'MAX_COMMENT_DEPTH': None, # Unlimited threading
'ALLOW_COMMENT_EDITING': True,
'EDIT_TIME_WINDOW': None, # Edit anytime
'TRACK_EDIT_HISTORY': True,
'SPAM_DETECTION_ENABLED': True,
'AUTO_BAN_AFTER_SPAM_FLAGS': 3,
}
๐ Security Considerations
XSS Protection
# HTML format with sanitization
DJANGO_COMMENTS_CONFIG = {
'COMMENT_FORMAT': 'html',
}
# Only these tags allowed by default:
# <p>, <br>, <strong>, <em>, <a>, <code>, <pre>, <ul>, <ol>, <li>
Rate Limiting
# Prevent spam/abuse
DJANGO_COMMENTS_CONFIG = {
'API_RATE_LIMIT': '100/day',
'API_RATE_LIMIT_ANON': '20/day',
'API_RATE_LIMIT_BURST': '5/min',
'MAX_FLAGS_PER_DAY': 20,
'MAX_FLAGS_PER_HOUR': 5,
}
Content Validation
# Automatic content checking
DJANGO_COMMENTS_CONFIG = {
'SPAM_DETECTION_ENABLED': True,
'PROFANITY_FILTERING': True,
'MAX_COMMENT_LENGTH': 3000,
}
๐ Performance Tips
Caching
Use Django's built-in database cache (no external service required):
python manage.py createcachetable
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'django_cache',
}
}
DJANGO_COMMENTS_CONFIG = {
'CACHE_TIMEOUT': 3600, # 1 hour
}
Memcached or Redis also work if already in your stack.
Database Optimization
# Use select_related and prefetch_related in queries
from django_comments.models import Comment
# Efficient querying
comments = Comment.objects.select_related('user', 'content_type').filter(
is_public=True
)
Async Notifications
# Uses built-in threading โ no broker needed
DJANGO_COMMENTS_CONFIG = {
'USE_ASYNC_NOTIFICATIONS': True,
}
๐ค Contributing
We love contributions! Here's how to get started:
- Fork the repository
- Create a feature branch
git checkout -b feature/amazing-feature
- Make your changes
- Run tests
python manage.py test django_comments
- Commit your changes
git commit -m "Add amazing feature"
- Push to your fork
git push origin feature/amazing-feature
- Open a Pull Request
Please check out our Contributing Guide for more details.
Development Setup
# Clone the repository
git clone https://github.com/NzeStan/django-reusable-comments.git
cd django-reusable-comments
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -e ".[dev]"
# Or install using requirements files
pip install -r requirements.txt
pip install -r requirements-dev.txt
# Run tests
pytest
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Support
- Documentation: Installation ยท Configuration ยท API Reference ยท Advanced Usage
- Issues: GitHub Issues
- Discussions: GitHub Discussions
๐ Changelog
See CHANGELOG.md for version history and changes.
๐ Credits
Developed and maintained by Ifeanyi Stanley Nnamani
Special thanks to all contributors who have helped improve this package!
๐ Star History
If you find this package useful, please consider giving it a โญ on GitHub!
๐ Quick Stats
- 280+ Tests - Comprehensive test coverage
- 60+ Settings - Complete configurability
- 8 Notification Types - Full email system
- GDPR Compliant - Privacy-first design
- Production Ready - Battle-tested code
Ready to add comments to your Django project? Install now and get started in 15 minutes! ๐
pip install django-reusable-comments
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_reusable_comments-1.0.0.tar.gz.
File metadata
- Download URL: django_reusable_comments-1.0.0.tar.gz
- Upload date:
- Size: 123.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a774bc33fee4a04d08a52a4c22faeb4e75b585f1777cb9b8184fdc890659e3a8
|
|
| MD5 |
c743d752c51058282150e23885be29b0
|
|
| BLAKE2b-256 |
9f039fe9600b86e50c4bc46625164a5e420739c11be800f961dcc8390a6affd1
|
File details
Details for the file django_reusable_comments-1.0.0-py3-none-any.whl.
File metadata
- Download URL: django_reusable_comments-1.0.0-py3-none-any.whl
- Upload date:
- Size: 81.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f163392290ae8517879ce615bfc810a088863c5a9fc8472aa40652dbdd2cedcf
|
|
| MD5 |
2d9404945b80e4b1e85de81efd877cb2
|
|
| BLAKE2b-256 |
7cecf775fd9b30c6ebe7728a4b53581ca4896f49e5f18960ebc61a295d582fd4
|