272 lines
10 KiB
Plaintext
272 lines
10 KiB
Plaintext
Metadata-Version: 2.4
|
|
Name: django-translatable-fields
|
|
Version: 0.1.1
|
|
Summary: Django plugin that mimics Odoo's translate=True functionality with admin interface integration
|
|
Author-email: Holger Sielaff <holger@backender.de>
|
|
Maintainer-email: Holger Sielaff <holger@backender.de>
|
|
License: MIT License
|
|
|
|
Copyright (c) 2024 Holger Sielaff
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
Project-URL: Homepage, https://repo.backender.de/holger/Django-Translatable-Fields
|
|
Project-URL: Documentation, https://repo.backender.de/holger/Django-Translatable-Fields#readme
|
|
Project-URL: Repository, https://repo.backender.de/holger/Django-Translatable-Fields.git
|
|
Project-URL: Bug Tracker, https://repo.backender.de/holger/Django-Translatable-Fields/issues
|
|
Project-URL: Changelog, https://repo.backender.de/holger/Django-Translatable-Fields/blob/main/CHANGELOG.md
|
|
Keywords: django,translation,internationalization,i18n,multilingual,translatable,fields,admin
|
|
Classifier: Development Status :: 4 - Beta
|
|
Classifier: Environment :: Web Environment
|
|
Classifier: Framework :: Django
|
|
Classifier: Framework :: Django :: 4.2
|
|
Classifier: Framework :: Django :: 5.0
|
|
Classifier: Framework :: Django :: 5.1
|
|
Classifier: Intended Audience :: Developers
|
|
Classifier: License :: OSI Approved :: MIT License
|
|
Classifier: Operating System :: OS Independent
|
|
Classifier: Programming Language :: Python
|
|
Classifier: Programming Language :: Python :: 3
|
|
Classifier: Programming Language :: Python :: 3.9
|
|
Classifier: Programming Language :: Python :: 3.10
|
|
Classifier: Programming Language :: Python :: 3.11
|
|
Classifier: Programming Language :: Python :: 3.12
|
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
Requires-Python: >=3.9
|
|
Description-Content-Type: text/markdown
|
|
License-File: LICENSE
|
|
Requires-Dist: Django>=4.2
|
|
Provides-Extra: dev
|
|
Requires-Dist: pytest; extra == "dev"
|
|
Requires-Dist: pytest-django; extra == "dev"
|
|
Requires-Dist: black; extra == "dev"
|
|
Requires-Dist: isort; extra == "dev"
|
|
Requires-Dist: flake8; extra == "dev"
|
|
Requires-Dist: mypy; extra == "dev"
|
|
Requires-Dist: django-stubs; extra == "dev"
|
|
Provides-Extra: drf
|
|
Requires-Dist: djangorestframework>=3.14.0; extra == "drf"
|
|
Dynamic: license-file
|
|
|
|
# Django Translatable Fields
|
|
|
|
[](https://badge.fury.io/py/django-translatable-fields)
|
|
[](https://pypi.org/project/django-translatable-fields/)
|
|
[](https://pypi.org/project/django-translatable-fields/)
|
|
[](LICENSE)
|
|
|
|
A Django plugin that mimics Odoo's `translate=True` functionality, providing automatic language-aware field handling with a beautiful admin interface integration.
|
|
|
|
## Features
|
|
|
|
- 🌍 **Language-Aware Fields**: Automatic translation handling based on Django's current language
|
|
- 📝 **Rich Admin Interface**: Modal overlay with WYSIWYG editor for easy translation management
|
|
- 🗄️ **JSON Storage**: Efficient storage of translations in a single database column
|
|
- 🔧 **Easy Integration**: Drop-in replacement for Django's standard fields
|
|
- 🎨 **Draggable & Resizable**: Modern modal interface with drag and resize capabilities
|
|
- 🚀 **DRF Support**: Built-in Django REST Framework serializers for API development
|
|
- ✅ **Field Validation**: Proper validation for Email, URL, and Slug fields per language
|
|
- 🎯 **Type Safety**: Full support for Django's field types with translation capabilities
|
|
|
|
## Quick Start
|
|
|
|
### 1. Installation
|
|
|
|
```bash
|
|
pip install django-translatable-fields
|
|
```
|
|
|
|
Add to your `INSTALLED_APPS`:
|
|
|
|
```python
|
|
INSTALLED_APPS = [
|
|
# ... other apps
|
|
'django_translatable_fields',
|
|
]
|
|
```
|
|
|
|
### 2. Define Your Model
|
|
|
|
```python
|
|
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):
|
|
name = CharField(max_length=200, translatable=True)
|
|
description = TextField(translatable=True)
|
|
slug = SlugField(max_length=200, translatable=True)
|
|
support_email = EmailField(translatable=True)
|
|
website = URLField(translatable=True)
|
|
price = models.DecimalField(max_digits=10, decimal_places=2)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
```
|
|
|
|
### 3. Configure Admin
|
|
|
|
```python
|
|
from django.contrib import admin
|
|
from django_translatable_fields.admin import TranslatableModelAdmin
|
|
from .models import Product
|
|
|
|
@admin.register(Product)
|
|
class ProductAdmin(TranslatableModelAdmin):
|
|
list_display = ['name', 'slug', 'price']
|
|
fields = ['name', 'description', 'slug', 'support_email', 'website', 'price']
|
|
prepopulated_fields = {'slug': ('name',)}
|
|
```
|
|
|
|
### 4. Usage
|
|
|
|
```python
|
|
from django.utils.translation import activate
|
|
|
|
# Create a product
|
|
product = Product.objects.create(
|
|
name="Awesome Product",
|
|
description="This is an amazing product",
|
|
slug="awesome-product",
|
|
support_email="support@example.com",
|
|
website="https://example.com",
|
|
price=29.99
|
|
)
|
|
|
|
# Set translations for all fields
|
|
product.name_en = "Awesome Product"
|
|
product.name_de = "Fantastisches Produkt"
|
|
product.name_fr = "Produit Fantastique"
|
|
|
|
product.description_en = "This is an amazing product"
|
|
product.description_de = "Das ist ein fantastisches Produkt"
|
|
product.description_fr = "C'est un produit fantastique"
|
|
|
|
product.slug_en = "awesome-product"
|
|
product.slug_de = "fantastisches-produkt"
|
|
product.slug_fr = "produit-fantastique"
|
|
|
|
product.support_email_en = "support@example.com"
|
|
product.support_email_de = "support@beispiel.de"
|
|
product.support_email_fr = "support@exemple.fr"
|
|
|
|
product.website_en = "https://example.com"
|
|
product.website_de = "https://beispiel.de"
|
|
product.website_fr = "https://exemple.fr"
|
|
|
|
product.save()
|
|
|
|
# Language-aware access
|
|
activate('en')
|
|
print(product.name) # "Awesome Product"
|
|
print(product.slug) # "awesome-product"
|
|
print(product.website) # "https://example.com"
|
|
|
|
activate('de')
|
|
print(product.name) # "Fantastisches Produkt"
|
|
print(product.slug) # "fantastisches-produkt"
|
|
print(product.website) # "https://beispiel.de"
|
|
|
|
activate('fr')
|
|
print(product.name) # "Produit Fantastique"
|
|
print(product.slug) # "produit-fantastique"
|
|
print(product.website) # "https://exemple.fr"
|
|
|
|
# Get all translations for any field
|
|
name_translations = product.get_all_translations('name')
|
|
print(name_translations) # {'en': 'Awesome Product', 'de': 'Fantastisches Produkt', 'fr': 'Produit Fantastique'}
|
|
|
|
url_translations = product.get_all_translations('website')
|
|
print(url_translations) # {'en': 'https://example.com', 'de': 'https://beispiel.de', 'fr': 'https://exemple.fr'}
|
|
```
|
|
|
|
## Admin Interface
|
|
|
|
The plugin provides an Odoo-style admin interface:
|
|
|
|
- **Primary Field**: Shows the default language (English) input field
|
|
- **Translate Button**: Click the translate icon (🌐) next to any translatable field
|
|
- **Modal Overlay**: Opens a modal with input fields for all configured languages
|
|
- **Clean Interface**: Only the primary language is visible initially, keeping the interface clean
|
|
|
|
Just like in Odoo, the translate functionality is accessed through a button next to each translatable field, opening an overlay with all language versions.
|
|
|
|
## Configuration
|
|
|
|
Configure your languages in Django settings:
|
|
|
|
```python
|
|
LANGUAGES = [
|
|
('en', 'English'),
|
|
('de', 'German'),
|
|
('fr', 'French'),
|
|
('es', 'Spanish'),
|
|
]
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Fields
|
|
|
|
- `CharField`: Like Django's `CharField` but with `translatable=True` parameter
|
|
- `TextField`: Like Django's `TextField` but with `translatable=True` parameter
|
|
- `EmailField`: Like Django's `EmailField` but with `translatable=True` parameter
|
|
- `URLField`: Like Django's `URLField` but with `translatable=True` parameter
|
|
- `SlugField`: Like Django's `SlugField` but with `translatable=True` parameter
|
|
|
|
Both fields accept a `translatable=True` parameter (default: True).
|
|
|
|
### Model Methods
|
|
|
|
When using `TranslatableModelMixin`:
|
|
|
|
- `obj.field_name`: Returns value in current language
|
|
- `obj.field_name_en`: Returns English translation
|
|
- `obj.get_translation(field_name, language_code)`: Get specific translation
|
|
- `obj.set_translation(field_name, language_code, value)`: Set specific translation
|
|
- `obj.get_all_translations(field_name)`: Get all translations as dict
|
|
|
|
### Admin Classes
|
|
|
|
- `TranslatableModelAdmin`: Use instead of `ModelAdmin` for automatic widget handling
|
|
- `TranslatableAdminMixin`: Mixin for custom admin classes
|
|
|
|
## Storage Format
|
|
|
|
Translations are stored as JSON in the database:
|
|
|
|
```json
|
|
{
|
|
"en": "Hello World",
|
|
"de": "Hallo Welt",
|
|
"fr": "Bonjour le monde"
|
|
}
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- Django >= 3.2
|
|
- Python >= 3.8
|
|
|
|
## License
|
|
|
|
MIT License
|