2

I'm using django-hvad for model translation, and not all of the models will have translations. I want the default to be en-us.

If a request is made for a particular language, the response should be in that language if the model has that translation available. If the translation is not available, I want en-us to be returned.

Right now what happens is I get an error 500: 'HttpResponse' object has no attribute '_meta'. This happens both when the translation is unavailable and when the language code isn't defined in LANGUAGES.

For example, I get the correct response with status 200 when I make a request for en-us:

GET http://localhost:5000/survey/surveys/2/?language=en-us

If I make a request for en-US I get a 500 error (note the change in caps from en-us to en-US):

GET http://localhost:5000/survey/surveys/2/?language=en-US

I get the same 500 error when requesting a language that is defined in LANGUAGES but doesn't have a translations:

GET http://localhost:5000/survey/surveys/2/?language=af

Here's the language section of my settings.py file:

settings.py

from django.utils.translation import ugettext_lazy as _

...
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True

LANGUAGES = [
    ('en-us', _('English')),
    ('af', _('Afrikaans')),
    ('ar', _('Arabic')),
    ...
    ]

If you're wondering about how this request is getting served up, here's the view for that URL:

views.py

class SurveyDetail(APIView):
    def get_object(self, pk):
        try:
            user_language = self.request.GET.get('language')
            return models.Survey.objects.language(user_language).get(pk=pk)
        except models.Survey.DoesNotExist:
            return HttpResponse(status=status.HTTP_404_NOT_FOUND)

    def get_related_questions(self, pk):
        try:
            user_language = self.request.GET.get('language')
            return models.SurveyQuestion.objects.language(user_language).all().filter(survey=pk)
        except models.SurveyAnswer.DoesNotExist:
            return HttpResponse(status=status.HTTP_404_NOT_FOUND)

    def get_related_answers(self, pk):
        try:
            user_language = self.request.GET.get('language')
            return models.SurveyAnswer.objects.language(user_language).all().filter(question=pk)
        except models.SurveyAnswer.DoesNotExist:
            return HttpResponse(status=status.HTTP_404_NOT_FOUND)

    def get(self, request, pk, format=None):
        survey = self.get_object(pk)
        questions = self.get_related_questions(pk)
        questions_serialized = []
        for q in questions:
            questions_serialized.append(SurveyQuestionSerializer(q).data)
            questions_serialized[-1]['answers']  = SurveyAnswerSerializer(self.get_related_answers(q.pk), many=True).data

        resp_obj = SurveySerializer(survey).data
        resp_obj['questions'] = questions_serialized

        return JSONResponse(resp_obj)
Kyle Falconer
  • 8,302
  • 6
  • 48
  • 68

1 Answers1

0

found this solution from https://github.com/spectras

https://github.com/KristianOellegaard/django-hvad/issues/136

class MyFallbackQueryset(FallbackQueryset):
    translation_fallbacks = (None, 'en', 'de', 'fr')  

class MyModel(TranslatableModel):
    objects = TranslationManager(fallback_class=MyFallbackQueryset)

None will be resolved to current language when query is evaluated. No re-ordering will be done, but due to the way the query works, having the same language appear twice does not matter. Also, it is now possible to override the default queryset (used when none of language, untranslated, … is called) the same way. For instance, simply passing default_class=MyFallbackQueryset should do the trick.

PeterN
  • 76
  • 4