Search code examples
pythondjangodjango-modelsdjango-simple-historydjango-modeltranslation

Trouble Integrating `django-simple-history` with `django-modeltranslation` in Abstract Model


I'm working on a Django project where I'm trying to create an abstract model that provides subclassed models with history tracking using the django-simple-history package. Additionally, I need to integrate django-modeltranslation for translating certain fields. However, I'm encountering issues with the integration.

Here's my BaseModel code:

from uuid import uuid4
from django.db import models
from simple_history.models import HistoricalRecords


class BaseModel(models.Model):
    class Meta:
        abstract = True

    history = HistoricalRecords(inherit=True)

    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True)
    updated_at = models.DateTimeField(null=True, blank=True, auto_now=True)

Now, I have a model TestModel that inherits from BaseModel:

models.py

class TestModel(BaseModel):
    text = models.CharField(max_length=100)
    un = models.IntegerField()
    new_text = models.CharField(max_length=100)

And for translating fields in TestModel, I have the following translation setup:

translation.py

from modeltranslation.translator import register, TranslationOptions
from test_app.models import TestDeleteModel


@register(TestModel)
class TestModelTranslationOptions(TranslationOptions):
    fields = (
        'text',
        'new_text',
    )

However, the issue arises when django-simple-history doesn't recognize the translated fields like text_en, resulting in them not being added to the history model. It seems that this occurs because the translation fields are added after the simple history package registers the model and creates the history model.

I attempted to register TestModel again with simple_history after the translation registration to address this:

translation.py

from modeltranslation.translator import register, TranslationOptions
import simple_history
from test_app.models import TestDeleteModel


@register(TestDeleteModel)
class TestDeleteModelTranslationOptions(TranslationOptions):
    fields = (
        'text',
        'new_text',
    )

simple_history.register(TestDeleteModel)

However, this resulted in a simple_history.exceptions.MultipleRegistrationsError with the message "TestModel registered multiple times for history tracking."

Any insights into resolving this issue would be greatly appreciated. Thanks in advance for your help!


Solution

  • I resolved this issue by creating two separate classes: one for registering the history with django-simple-history and another that can be used after adding the translation fields. This way, we avoid the MultipleRegistrationsError and ensure that the translation fields are properly recognized.

    from uuid import uuid4
    from django.db import models
    from simple_history.models import HistoricalRecords
    
    
    class BaseModel(SafeDeleteModel):
        class Meta:
            abstract = True
    
        id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
        created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True)
        updated_at = models.DateTimeField(null=True, blank=True, auto_now=True)
    
    
    class HistoricalBaseModel(AuditModel):
        class Meta:
            abstract = True
    
        history = HistoricalRecords(inherit=True)