Fact Box
Language Python
License BSD
GitHub KristianOellegaard/django-hvad
PyPI django-hvad
First Release 2011
Status Archived

django-hvad (which means "what" in Danish) is a translation framework for Django models that makes internationalization painless. It allows you to translate your Django models into multiple languages using the normal Django ORM, without the complexity and performance overhead of other solutions.

Origins

django-hvad started as a fork of django-nani by Jonas Obrist. While django-nani provided the foundational concepts, I created hvad to take the project in a new direction with different design choices and features. The fork allowed the community to explore different approaches to solving Django translation challenges.

The Translation Problem

When building international Django applications, I quickly discovered that handling translations for database content was surprisingly difficult. The existing solutions at the time had significant drawbacks:

  • Required complex queries and custom managers
  • Added multiple database queries for translated content
  • Broke standard Django ORM patterns
  • Made it difficult to work with translated and non-translated models consistently

I wanted something that felt natural - where you could just use the Django ORM as usual, and it would automatically handle translations based on the current language.

The hvad Approach

django-hvad introduced a simple yet powerful pattern:

class Product(TranslatableModel):
    # Non-translated fields
    price = models.DecimalField()
    sku = models.CharField()

    translations = TranslatedFields(
        # Translated fields
        name=models.CharField(max_length=255),
        description=models.TextField(),
    )

Key Innovations

1. Transparent ORM Integration

Once configured, you work with translated models just like regular Django models:

# Automatically returns content in the current language
product = Product.objects.language('da').get(sku='ABC123')
print(product.name)  # Returns Danish name

2. Performance Optimization

Unlike solutions that required separate queries for translations, hvad uses an INNER JOIN to an indexed key. This meant:

  • No additional queries for reads
  • Minimal performance overhead
  • Efficient database utilization

3. Natural Fallbacks

The library handled language fallbacks gracefully - if a translation didn't exist in the requested language, it could fall back to a default language automatically.

4. Complete QuerySet Support

You could filter, order, and aggregate using translated fields just like any other Django field:

Product.objects.language('en').filter(name__icontains='laptop').order_by('name')

Design Philosophy

Several principles guided hvad's development:

  • Unobtrusive: Shouldn't require rethinking how you write Django applications
  • Efficient: Performance should be comparable to non-translated models
  • Reliable: Extensive test coverage (300+ test cases)
  • Compatible: Work seamlessly with existing Django projects

Migration Path

One of hvad's strengths was easy migration from django-multilingual-ng, the previous popular solution. This made it practical for existing projects to adopt hvad without a complete rewrite.

Real-World Impact

django-hvad was adopted by numerous Django projects that needed multi-language support:

  • E-commerce platforms serving multiple markets
  • Content management systems
  • SaaS applications with international customers
  • Government and institutional websites

The project proved that you could build powerful abstractions while maintaining simplicity and performance.

Evolution and Legacy

After several years of active development and maintenance, I handed off the project to other maintainers. The project remained actively maintained through Django 1.11.

Eventually, the Django community converged around django-parler as the recommended translation solution, which built upon many of the concepts pioneered in hvad and nani while taking the implementation in new directions.

Technical Achievements

django-hvad demonstrated several important technical concepts:

Custom QuerySet Magic: Showed how to extend Django's ORM in powerful but intuitive ways

Translation Layer Design: Proved that translation frameworks don't need to be complex to be powerful

Test-Driven Development: Maintained reliability through comprehensive test coverage

API Design: Created an API that felt natural to Django developers

Lessons in Open Source

Building and maintaining django-hvad taught me important lessons about open source projects:

  • Solve Real Problems: The best libraries emerge from actual needs, not theoretical exercises
  • Standing on Shoulders: Forking django-nani gave us a foundation to build upon and explore different directions
  • API Design Matters: A good API can make complex problems feel simple
  • Community Building: Successful projects require more than code - they need documentation, examples, and responsive maintenance
  • Know When to Let Go: Sometimes the best thing you can do for a project is hand it off to maintainers who can take it further

Why "hvad"?

The name "hvad" (Danish for "what") was chosen as a nod to my Danish heritage and as a playful reference to the question developers often ask: "what's the translation for this content?" The name stuck, and became part of the Django ecosystem's colorful naming tradition.

Lasting Impact

While django-hvad itself is no longer actively maintained, its influence lives on. The patterns and approaches it pioneered can be seen in modern Django translation frameworks. It proved that internationalization doesn't have to be painful and that good abstraction layers can make complex problems tractable.

For me, django-hvad represents an important lesson: the best tools are often invisible. They solve a hard problem so well that users barely notice they're there - they just get to focus on building their applications.

Credit

Thanks to Jonas Obrist for creating django-nani, which provided the foundation for hvad. The open source community thrives when we build upon each other's work.