5

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?

oz123
  • 27,559
  • 27
  • 125
  • 187
Philipp Zedler
  • 1,660
  • 1
  • 17
  • 36

2 Answers2

6

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)
niceguydave
  • 401
  • 2
  • 12
  • Thanks, this line fixed an incompatibility between Haystack and Hvad, where Hvad forces the object to be saved in the admin interface, and Haystack tries to index it immediately, before the translations are written. Preparing the value using `self.lazy_translation_getter('title')` made it work for me. – qris Oct 30 '13 at 16:58
0

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()
Risadinha
  • 16,058
  • 2
  • 88
  • 91