Search code examples
djangourl-pattern

Issue using i18n_patterns with API


I have an app which includes a website and an API. I have translated the website to a second language. The main language is currently English and the second one Farsi. I have used i18n_patterns in urlpatterns to redirect between the two languages. The issue is when using the API, it seems like Django redirects my request and since the data is sent using POST, it drops all data and gives me an empty result using GET. I tried taking the API url out of the urlpattern and then appending it which solves this issue, but that doesn't work since I need to have Unicode support for Farsi and since there is no i18n_patterns support this way, I get an unintelligible response.
This is the Urlpattern:

urlpatterns = i18n_patterns(
    path('admin/', admin.site.urls),
    path('mainapp/', include('mainapp.urls')),
    path('', include('mainapp.urls')),
    prefix_default_language=True
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

urlpatterns.append(path('api/', include('mainapp.api.urls')))

Is there any way I can solve this issue with the least possible change to the app? Any help, suggestion, or guidance would be very much appreciated.

EDIT: Thank you. I changed the code to reproduce the issue. I call http://localhost:8000/api/scan/. If I add the path('api/', include('mainapp.api.urls')) to the original urlpattern with i18n_patterns, and send the request to API, the request.POST value is <QueryDict: {}> while otherwise it should send a key:value to the backend. I looked around and it seems when you add i18n_patterns to urlpatterns, a redirect happens and since HTTP doesn't allow POST data redirects, I get an empty response.


Solution

  • The goal of i18n_patterns is to translate the url itself, so it's a bit weird that you'd want to that for an API. The idea is that users who look at the address bar in their browser read the urls and it might help to translate them so it's easier for them to understand where they are on your site. So for example if you have a url "/shop/product/" in English and you want it to be "/magazin/produit/" in French.

    Since an API doesn't display URLs to end-users, it just doesn't make sense to have the API urls fall under i18n_patterns. That will solve the redirect issue.

    Your original problem is that your view returns an "unintelligible response" when you call it using an URL which doesn't specify the language. That's probably because the view is detecting the wrong language. This is how Django detects the language preference. So if the url doesn't have the information, it will:

    • Look for the language cookie.
    • Look at the Accept-Language HTTP header, in this order.

    So you can either ensure your API requests set the correct header (and don't send the language cookie), or you can just set the active language in each view called by the API.