Skip to content

Commit

Permalink
Merge pull request #6 from Nabute/refactor/lisan-translation-dynamic-…
Browse files Browse the repository at this point in the history
…filter

Fix: Refactor Lisan Translation Handling to Support Dynamic Fields
  • Loading branch information
Nabute authored Dec 10, 2024
2 parents 313c8d9 + c2efa7f commit 2906b9c
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 72 deletions.
2 changes: 0 additions & 2 deletions lisan/metaclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ def clean(self):
attrs
)

print(f"Generated Lisan model for {model_cls.__name__}") # noqa

return lisan_model


Expand Down
20 changes: 13 additions & 7 deletions lisan/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ def get_lisan(self, language_code=None):
"""
language_code = language_code or self._current_language
try:
return self.Lisan.objects.filter(
language_code=language_code).first()
filter_kwargs = {
"language_code": language_code,
f"{self._meta.model_name}": self
}
return self.Lisan.objects.filter(**filter_kwargs).first()
except ObjectDoesNotExist:
return None
except Exception as e:
Expand Down Expand Up @@ -63,9 +66,11 @@ def set_lisan(self, language_code, **lisan_fields):

try:
with transaction.atomic():
lisan = self.Lisan.objects.filter(
language_code=language_code
).first()
filter_kwargs = {
"language_code": language_code,
f"{self._meta.model_name}": self
}
lisan = self.Lisan.objects.filter(**filter_kwargs).first()

if not lisan:
# Check if all lisan_fields exist in the model
Expand Down Expand Up @@ -159,8 +164,9 @@ def set_bulk_lisans(self, translations):
consistency.
"""
with transaction.atomic():
for language_code, fields in translations.items():
self.set_lisan(language_code, **fields)
for translation in translations:
language_code = translation.pop("language_code")
self.set_lisan(language_code, **translation)

def get_lisan_field(
self, field_name,
Expand Down
27 changes: 1 addition & 26 deletions lisan/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,24 +108,6 @@ def to_representation(self, instance):
representation['translations'] = translations_representation
return representation

def _process_translations(
self, instance, translations, default_language_code):
"""
Process and save the translations for each language provided
in the translations list. This method updates the instance with
language-specific data.
"""
for translation in translations:
lang_code = translation.pop('language_code', None)
if lang_code:
lisan_data = {
field: translation.get(field)
for field in instance.lisan_fields
if translation.get(field) is not None
}
if lisan_data:
instance.set_lisan(lang_code, **lisan_data)

def create(self, validated_data):
"""
Create a new instance of the model, handling any translations
Expand All @@ -145,14 +127,7 @@ def create(self, validated_data):

# Create the main instance
instance = super().create(validated_data)
lisan_fields = {
field: validated_data.get(field)
for field in self.Meta.model.lisan_fields
}
instance.set_lisan(language_code, **lisan_fields)

# Process and save the translations
self._process_translations(instance, translations, language_code)
instance.set_bulk_lisans(translations)

return instance

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def read_file(filename):

setup(
name='lisan',
version='0.1.6',
version='0.1.7',
packages=find_packages(),
include_package_data=True,
license='MIT',
Expand Down
38 changes: 26 additions & 12 deletions tests/test_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,24 @@ def test_set_bulk_lisans(self):
"""
Test setting translations in bulk for multiple languages.
"""
translations = {
'am': {'title': "አዲስ ሰላም"},
'or': {'title': "Nagaa Addunyaa", 'description': "Fakkeenya"}
}
translations = [
{
"language_code": "or",
"title": "Nagaa Addunyaa",
"description": "Fakkeenya"
},
{
"language_code": "am",
"title": "አስደሳች ጉዞ",
"description": "በማይታወቁ መሬቶች ላይ አስገራሚ ጉዞ."
}
]
self.instance.set_bulk_lisans(translations)

am_translation = self.instance.get_lisan('am')
or_translation = self.instance.get_lisan('or')

self.assertEqual(am_translation.title, "አዲስ ሰላም")
self.assertEqual(am_translation.title, "አስደሳች ጉዞ")
self.assertEqual(or_translation.title, "Nagaa Addunyaa")
self.assertEqual(or_translation.description, "Fakkeenya")

Expand Down Expand Up @@ -246,17 +254,23 @@ def test_set_bulk_lisans_updates_and_creates_translations(self):
Test that set_bulk_lisans updates existing translations and creates
new translations as needed.
"""
translations = {
# Update existing translation
'am': {'title': "አዲስ ሰላም"},
# New translation
'or': {'title': "Nagaa Addunyaa", 'description': "Fakkeenya"},
}
translations = [
{
"language_code": "or",
"title": "Nagaa Addunyaa",
"description": "Fakkeenya"
},
{
"language_code": "am",
"title": "አስደሳች ጉዞ",
"description": "ምሳሌ መግለጫ"
}
]
self.instance.set_bulk_lisans(translations)

# Verify the 'am' translation was updated
am_translation = self.instance.get_lisan('am')
self.assertEqual(am_translation.title, "አዲስ ሰላም")
self.assertEqual(am_translation.title, "አስደሳች ጉዞ")
# Unchanged field
self.assertEqual(am_translation.description, "ምሳሌ መግለጫ")

Expand Down
24 changes: 0 additions & 24 deletions tests/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,30 +213,6 @@ def test_representation_unsupported_language(self):
self.assertEqual(representation['title'], "Hello World")
self.assertEqual(representation['description'], "Sample description")

def test_process_translations_empty_data(self):
"""
Test that `_process_translations` handles empty
translations gracefully.
"""
serializer = self.serializer_class(context={'request': self.request})
serializer._process_translations(self.model_instance, [], 'en')
# Ensure no exceptions and instance remains unchanged
self.assertEqual(self.model_instance.get_lisan_field(
'title', 'am'), "ሰላም")

def test_process_translations_with_missing_language_code(self):
"""
Test `_process_translations` with a translation missing a
language_code.
"""
serializer = self.serializer_class(context={'request': self.request})
translations = [{'title': "Missing Language Code"}]
serializer._process_translations(
self.model_instance, translations, 'en')
# Ensure no exceptions and instance remains unchanged
self.assertEqual(self.model_instance.get_lisan_field(
'title', 'am'), "ሰላም")

def test_validate_translations_partial(self):
"""
Test validation with partial translations in partial update mode.
Expand Down

0 comments on commit 2906b9c

Please sign in to comment.