django-hvad - how should I set a translated field value while saving a model instance?

2k views Asked by At

Background: I use django-hvad and have a TranslatableModel. In its TranslatedFields I have a slug attribute which should be automatically created using the title attribute while saving the model.

Problem: It is difficult to set the value of one of the TranslatedFields while saving the instance. A solution that works is to override the save_translations method of my TranslatableModel as follows. Only the second last line differs from the original:

    @classmethod
    def save_translations(cls, instance, **kwargs):
        """
        The following is copied an pasted from the TranslatableModel class.
        """
        opts = cls._meta
        if hasattr(instance, opts.translations_cache):
            trans = getattr(instance, opts.translations_cache)
            if not trans.master_id:
                trans.master = instance
            # The following line is different from the original.
            trans.slug = defaultfilters.slugify(trans.title)
            trans.save()

This solution is not nice, because it makes use of copy and paste. Is there a better way to achieve the same?

2

There are 2 answers

1
niceguydave On

The following answer assumes that you are using the admin system to auto-generate slug from title. This may or may not be your exact situation but it may be relevant.

This is an extension of the explanation within the Django-hvad project pages.

The way to implement your feature is within the the admin.py file within your app. You need to extend the __init__() method of the TranslatableAdmin class.

Say, for example, your model is called Entry. The simplified code in models.py could be along the lines of the following:

from django.db import models
from hvad.models import TranslatableModel, TranslatedFields

class Entry(TranslatableModel):
    translations = TranslatedFields(
        title=models.CharField(max_length=100,),
        slug=models.SlugField(),
        meta={'unique_together': [('language_code', 'slug')]},
    )
    def __unicode__(self):
        return self.lazy_translation_getter('title')

Your corresponding admin.py file should then be as follows:

from django.contrib import admin

from hvad.admin import TranslatableAdmin

from .models import Entry

class EntryAdmin(TranslatableAdmin):
    def __init__(self, *args, **kwargs):
        super(EntryAdmin, self).__init__(*args, **kwargs)
        self.prepopulated_fields = {'slug': ('title',)}

admin.site.register(Entry, EntryAdmin)
0
Risadinha On

Using django-hvad 1.5.0.

Use case: setting the value of a TranslatableModel field outside outside the Django Admin.

# self is a TranslatableModel instance with `translations`
# this first line will initialize the cache if necessary
slug = self.lazy_translation_getter('slug')
translation = get_cached_translation(self)
translation.master = self
translation.slug = defaultfilters.slugify(self.title)  # whatever value
translation.save()