Initial
This commit is contained in:
166
example/README.md
Normal file
166
example/README.md
Normal 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
1
example/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Example app for django-translatable-fields
|
||||
60
example/admin.py
Normal file
60
example/admin.py
Normal 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
91
example/models.py
Normal 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
263
example/usage_examples.py
Normal 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()
|
||||
Reference in New Issue
Block a user