This commit is contained in:
Holger Sielaff
2025-08-02 20:08:33 +02:00
commit 79c68169f6
47 changed files with 4880 additions and 0 deletions

166
example/README.md Normal file
View File

@@ -0,0 +1,166 @@
# Django Translatable Fields - Examples
This directory contains comprehensive examples demonstrating all features of django-translatable-fields.
## Files Overview
- **`models.py`** - Example models showcasing all translatable field types
- **`admin.py`** - Admin configurations for the example models
- **`usage_examples.py`** - Practical usage examples and demonstrations
## Example Models
### 1. Product Model
Demonstrates basic translatable fields:
- `CharField` - Product name
- `TextField` - Product description
- `SlugField` - SEO-friendly URL slug
- `EmailField` - Support contact email
- `URLField` - Product website URL
### 2. Category Model
Shows category organization with translations:
- `CharField` - Category name
- `TextField` - Category description
- `SlugField` - URL-friendly category slug
- `CharField` - SEO meta description
### 3. BlogPost Model
Comprehensive example with all field types:
- `CharField` - Blog post title and meta description
- `TextField` - Main blog post content
- `SlugField` - URL slug for the post
- `EmailField` - Author contact email
- `URLField` - External reference URL
### 4. Company Model
Business-focused model with contact information:
- `CharField` - Company name
- `TextField` - Company description and address
- `SlugField` - Company URL slug
- `EmailField` - Main contact email
- `URLField` - Company website
## Running the Examples
### 1. Django Shell Usage
```python
# Start Django shell
python manage.py shell
# Import and run examples
from example.usage_examples import run_all_examples
run_all_examples()
```
### 2. Individual Example Functions
```python
from example.usage_examples import (
create_sample_data,
demonstrate_language_switching,
demonstrate_direct_access,
demonstrate_translation_methods,
demonstrate_all_field_types
)
# Create sample data
product, blog_post, company = create_sample_data()
# Try different demonstrations
demonstrate_language_switching()
demonstrate_direct_access()
demonstrate_translation_methods()
demonstrate_all_field_types()
```
## Usage Patterns Demonstrated
### 1. Language-Aware Access
```python
from django.utils.translation import activate
# Fields automatically return values based on current language
activate('en')
print(product.name) # "Awesome Widget"
activate('de')
print(product.name) # "Fantastisches Widget"
```
### 2. Direct Language Access
```python
# Access specific language directly
print(product.name_en) # "Awesome Widget"
print(product.name_de) # "Fantastisches Widget"
print(product.name_fr) # "Widget Fantastique"
```
### 3. Translation Management
```python
# Get all translations for a field
translations = product.get_all_translations('name')
# {'en': 'Awesome Widget', 'de': 'Fantastisches Widget', 'fr': 'Widget Fantastique'}
# Get specific translation
german_name = product.get_translation('name', 'de')
# Set translation programmatically
product.set_translation('name', 'es', 'Widget Fantástico')
product.save()
```
### 4. All Field Types in Action
The examples demonstrate proper usage of:
- **CharField** - Text fields with max_length
- **TextField** - Longer text content
- **SlugField** - URL-friendly identifiers
- **EmailField** - Email addresses with validation
- **URLField** - Web URLs with validation
## Admin Interface Features
The admin examples show:
- Clean interface with translate buttons
- Modal overlays for translation management
- WYSIWYG editor for TextField content
- Proper field validation per language
- Drag and resize functionality for modals
## Field Validation
Each field type includes proper validation:
- **EmailField** - Valid email format per language
- **URLField** - Valid URL format per language
- **SlugField** - Slug format validation per language
- **CharField/TextField** - Length and content validation
## Integration with Django Features
Examples demonstrate compatibility with:
- Django admin interface
- Model forms and validation
- Django's internationalization system
- Search functionality
- List filters and display options
- Prepopulated fields (for slugs)
## Best Practices Shown
1. **Model Design** - Proper use of translatable vs non-translatable fields
2. **Admin Configuration** - Clean, user-friendly admin interfaces
3. **Data Access** - Efficient translation retrieval and management
4. **Validation** - Proper field validation across languages
5. **SEO Optimization** - Language-specific slugs and meta descriptions
## Testing Your Implementation
Use these examples to:
1. Verify all field types work correctly
2. Test language switching functionality
3. Validate admin interface behavior
4. Check translation storage and retrieval
5. Ensure proper field validation
The examples provide a solid foundation for implementing translatable fields in your own Django applications.

1
example/__init__.py Normal file
View File

@@ -0,0 +1 @@
# Example app for django-translatable-fields

60
example/admin.py Normal file
View File

@@ -0,0 +1,60 @@
"""
Example admin configuration demonstrating django-translatable-fields usage.
"""
from django.contrib import admin
from django_translatable_fields.admin import TranslatableModelAdmin
from .models import Product, Category, BlogPost, Company
@admin.register(Product)
class ProductAdmin(TranslatableModelAdmin):
"""
Admin for Product model with translatable fields.
"""
list_display = ['name', 'slug', 'price', 'created_at']
list_filter = ['created_at']
search_fields = ['name', 'description']
fields = ['name', 'description', 'slug', 'support_email', 'website', 'price']
prepopulated_fields = {'slug': ('name',)}
@admin.register(Category)
class CategoryAdmin(TranslatableModelAdmin):
"""
Admin for Category model with translatable fields.
"""
list_display = ['name', 'slug']
search_fields = ['name', 'description']
fields = ['name', 'description', 'slug', 'meta_description']
prepopulated_fields = {'slug': ('name',)}
@admin.register(BlogPost)
class BlogPostAdmin(TranslatableModelAdmin):
"""
Admin for BlogPost model demonstrating all translatable field types.
"""
list_display = ['title', 'slug', 'published', 'publish_date', 'created_at']
list_filter = ['published', 'publish_date', 'created_at']
search_fields = ['title', 'content', 'meta_description']
fields = [
'title', 'content', 'slug', 'author_email', 'external_link',
'meta_description', 'published', 'publish_date'
]
prepopulated_fields = {'slug': ('title',)}
date_hierarchy = 'created_at'
@admin.register(Company)
class CompanyAdmin(TranslatableModelAdmin):
"""
Admin for Company model with comprehensive translatable fields.
"""
list_display = ['name', 'slug', 'contact_email', 'founded_year', 'is_active']
list_filter = ['is_active', 'founded_year']
search_fields = ['name', 'description', 'address']
fields = [
'name', 'description', 'slug', 'contact_email', 'website',
'address', 'founded_year', 'employee_count', 'is_active'
]
prepopulated_fields = {'slug': ('name',)}

91
example/models.py Normal file
View File

@@ -0,0 +1,91 @@
"""
Example models demonstrating django-translatable-fields usage.
"""
from django.db import models
from django_translatable_fields.fields import CharField, TextField, EmailField, URLField, SlugField
from django_translatable_fields.descriptors import TranslatableModelMixin
class Product(TranslatableModelMixin, models.Model):
"""
Example product model with translatable fields.
"""
name = CharField(max_length=200, translatable=True, help_text="Product name")
description = TextField(translatable=True, help_text="Product description")
slug = SlugField(max_length=200, translatable=True, help_text="SEO-friendly URL slug")
support_email = EmailField(translatable=True, help_text="Support contact email")
website = URLField(translatable=True, blank=True, help_text="Product website URL")
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
app_label = 'example'
def __str__(self):
return self.name or f"Product {self.id}"
class Category(TranslatableModelMixin, models.Model):
"""
Example category model with translatable fields.
"""
name = CharField(max_length=100, translatable=True, help_text="Category name")
description = TextField(translatable=True, blank=True, help_text="Category description")
slug = SlugField(max_length=100, translatable=True, help_text="URL-friendly category slug")
meta_description = CharField(max_length=160, translatable=True, blank=True, help_text="SEO meta description")
class Meta:
app_label = 'example'
verbose_name_plural = "Categories"
def __str__(self):
return self.name or f"Category {self.id}"
class BlogPost(TranslatableModelMixin, models.Model):
"""
Example blog post model demonstrating all translatable field types.
"""
title = CharField(max_length=200, translatable=True, help_text="Blog post title")
content = TextField(translatable=True, help_text="Main blog post content")
slug = SlugField(max_length=200, translatable=True, help_text="URL slug for the post")
author_email = EmailField(translatable=True, help_text="Author contact email")
external_link = URLField(translatable=True, blank=True, help_text="External reference URL")
meta_description = CharField(max_length=160, translatable=True, blank=True, help_text="SEO meta description")
# Non-translatable fields
published = models.BooleanField(default=False)
publish_date = models.DateTimeField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
app_label = 'example'
ordering = ['-created_at']
def __str__(self):
return self.title or f"Blog Post {self.id}"
class Company(TranslatableModelMixin, models.Model):
"""
Example company model with contact information in multiple languages.
"""
name = CharField(max_length=200, translatable=True, help_text="Company name")
description = TextField(translatable=True, help_text="Company description")
slug = SlugField(max_length=200, translatable=True, help_text="Company URL slug")
contact_email = EmailField(translatable=True, help_text="Main contact email")
website = URLField(translatable=True, help_text="Company website")
address = TextField(translatable=True, help_text="Company address")
# Non-translatable fields
founded_year = models.IntegerField(null=True, blank=True)
employee_count = models.IntegerField(null=True, blank=True)
is_active = models.BooleanField(default=True)
class Meta:
app_label = 'example'
verbose_name_plural = "Companies"
def __str__(self):
return self.name or f"Company {self.id}"

263
example/usage_examples.py Normal file
View File

@@ -0,0 +1,263 @@
"""
Usage examples for django-translatable-fields demonstrating all field types.
This file shows practical examples of how to work with translatable fields
in various scenarios, including data creation, language switching, and
accessing translations programmatically.
"""
from django.utils.translation import activate, get_language
from .models import Product, Category, BlogPost, Company
def create_sample_data():
"""
Create sample data with translations in multiple languages.
"""
print("Creating sample data with translations...")
# Create a product with all field types
product = Product.objects.create(
name="Awesome Widget",
description="This is an amazing product that does everything you need.",
slug="awesome-widget",
support_email="support@example.com",
website="https://example.com/products/awesome-widget",
price=99.99
)
# Add German translations
product.name_de = "Fantastisches Widget"
product.description_de = "Das ist ein fantastisches Produkt, das alles macht, was Sie brauchen."
product.slug_de = "fantastisches-widget"
product.support_email_de = "support@beispiel.de"
product.website_de = "https://beispiel.de/produkte/fantastisches-widget"
# Add French translations
product.name_fr = "Widget Fantastique"
product.description_fr = "C'est un produit fantastique qui fait tout ce dont vous avez besoin."
product.slug_fr = "widget-fantastique"
product.support_email_fr = "support@exemple.fr"
product.website_fr = "https://exemple.fr/produits/widget-fantastique"
product.save()
# Create a blog post
blog_post = BlogPost.objects.create(
title="How to Use Awesome Widgets",
content="This comprehensive guide will show you everything about widgets...",
slug="how-to-use-awesome-widgets",
author_email="author@example.com",
external_link="https://external-resource.com",
meta_description="Complete guide to using awesome widgets effectively",
published=True
)
# Add translations for blog post
blog_post.title_de = "Wie man fantastische Widgets verwendet"
blog_post.content_de = "Dieser umfassende Leitfaden zeigt Ihnen alles über Widgets..."
blog_post.slug_de = "wie-man-fantastische-widgets-verwendet"
blog_post.author_email_de = "autor@beispiel.de"
blog_post.external_link_de = "https://externe-ressource.de"
blog_post.meta_description_de = "Vollständiger Leitfaden zur effektiven Nutzung fantastischer Widgets"
blog_post.save()
# Create a company
company = Company.objects.create(
name="Tech Innovations Inc.",
description="Leading technology company specializing in innovative solutions.",
slug="tech-innovations",
contact_email="contact@techinnovations.com",
website="https://techinnovations.com",
address="123 Tech Street, Silicon Valley, CA 94000",
founded_year=2010,
employee_count=150
)
# Add translations for company
company.name_de = "Tech Innovationen GmbH"
company.description_de = "Führendes Technologieunternehmen mit Spezialisierung auf innovative Lösungen."
company.slug_de = "tech-innovationen"
company.contact_email_de = "kontakt@techinnovationen.de"
company.website_de = "https://techinnovationen.de"
company.address_de = "Techstraße 123, 10115 Berlin, Deutschland"
company.save()
return product, blog_post, company
def demonstrate_language_switching():
"""
Demonstrate how fields automatically return values based on current language.
"""
print("\nDemonstrating language-aware field access...")
# Get a product (assuming one exists)
try:
product = Product.objects.first()
if not product:
print("No products found. Create sample data first.")
return
print(f"Current language: {get_language()}")
# English
activate('en')
print(f"English - Name: {product.name}")
print(f"English - Website: {product.website}")
print(f"English - Email: {product.support_email}")
# German
activate('de')
print(f"German - Name: {product.name}")
print(f"German - Website: {product.website}")
print(f"German - Email: {product.support_email}")
# French
activate('fr')
print(f"French - Name: {product.name}")
print(f"French - Website: {product.website}")
print(f"French - Email: {product.support_email}")
# Reset to English
activate('en')
except Exception as e:
print(f"Error: {e}")
def demonstrate_direct_access():
"""
Demonstrate direct access to specific language translations.
"""
print("\nDemonstrating direct language access...")
try:
product = Product.objects.first()
if not product:
print("No products found. Create sample data first.")
return
print("Direct access to specific languages:")
print(f"English name: {product.name_en}")
print(f"German name: {product.name_de}")
print(f"French name: {product.name_fr}")
print(f"English slug: {product.slug_en}")
print(f"German slug: {product.slug_de}")
print(f"French slug: {product.slug_fr}")
except Exception as e:
print(f"Error: {e}")
def demonstrate_translation_methods():
"""
Demonstrate helper methods for working with translations.
"""
print("\nDemonstrating translation helper methods...")
try:
product = Product.objects.first()
if not product:
print("No products found. Create sample data first.")
return
# Get all translations for a field
name_translations = product.get_all_translations('name')
print(f"All name translations: {name_translations}")
website_translations = product.get_all_translations('website')
print(f"All website translations: {website_translations}")
# Get specific translation
german_name = product.get_translation('name', 'de')
print(f"German name via method: {german_name}")
# Set translation programmatically
product.set_translation('name', 'es', 'Widget Fantástico')
product.save()
spanish_name = product.get_translation('name', 'es')
print(f"Spanish name (newly set): {spanish_name}")
except Exception as e:
print(f"Error: {e}")
def demonstrate_all_field_types():
"""
Demonstrate all available translatable field types.
"""
print("\nDemonstrating all translatable field types...")
try:
# Create an instance with all field types
company = Company.objects.create(
name="Demo Company", # CharField
description="This is a demo company.", # TextField
slug="demo-company", # SlugField
contact_email="demo@company.com", # EmailField
website="https://democompany.com", # URLField
address="123 Demo Street, Demo City" # TextField
)
print("Created company with all field types:")
print(f"CharField (name): {company.name}")
print(f"TextField (description): {company.description}")
print(f"SlugField (slug): {company.slug}")
print(f"EmailField (contact_email): {company.contact_email}")
print(f"URLField (website): {company.website}")
print(f"TextField (address): {company.address}")
# Add translations for each field type
company.name_de = "Demo Firma"
company.description_de = "Das ist eine Demo-Firma."
company.slug_de = "demo-firma"
company.contact_email_de = "demo@firma.de"
company.website_de = "https://demofirma.de"
company.address_de = "Demostraße 123, Demo Stadt"
company.save()
activate('de')
print("\nGerman translations:")
print(f"CharField (name): {company.name}")
print(f"TextField (description): {company.description}")
print(f"SlugField (slug): {company.slug}")
print(f"EmailField (contact_email): {company.contact_email}")
print(f"URLField (website): {company.website}")
print(f"TextField (address): {company.address}")
activate('en') # Reset
except Exception as e:
print(f"Error: {e}")
def run_all_examples():
"""
Run all examples in sequence.
"""
print("=== Django Translatable Fields - Usage Examples ===")
# Create sample data
product, blog_post, company = create_sample_data()
# Run demonstrations
demonstrate_language_switching()
demonstrate_direct_access()
demonstrate_translation_methods()
demonstrate_all_field_types()
print("\n=== Examples completed successfully! ===")
if __name__ == "__main__":
# This can be run in Django shell with:
# python manage.py shell
# >>> from example.usage_examples import run_all_examples
# >>> run_all_examples()
run_all_examples()