Issue using i18n_patterns with API - django

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.

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.

Not sure I understand your problem fully, but you can prevent the redirects by setting redirect_on_fallback to False in your CMS_LANGUAGES settings.

Related

django project derived from python-socketio django example unable to server other URLs (at least in django 1.11)

After playing with python-socketios django_example, and seeing that it worked great, I created a new django project, configured it just like the example, copied over the example app to the project (complete with it's overriding of the runserver management command). Everything worked fine, and I was able to make my a few changes so that you can set a nick, some redis stuff to lookup up the sid for a nick, and was able to support sending private messages to a nick. Everything was still working great.
I figured the next logical step was to, rather than having to manually set a nick, require the user to login, expose their username as a var in a script block in the template (I moved scripts/index.html to templates/index.html), and automatically have the javascript emit my custom 'set_nick' event with the username automatically upon connect.
I defined LOGIN_URL = '/accounts/login' in settings.py, included 'django.contrib.auth.urls' in my urls.py and wrapped the index view with #login_required.
It was only then that I noticed that no matter what URL you request, you always get the chat apps index view - no login page redirect, '/admin/' is ignored, etc.
EDIT Solved - See my answer below.
I noticed that the urls.py which I blindly copied over from the example looked like this:
url(r'', include('socketio_app.urls')),
url(r'^admin/', admin.site.urls),
and the r'' was the culprit (matches everthing). Changing this to:
url(r'^/', include('socketio_app.urls)),
url(r'^admin/', admin.site.urls),
However, I'm using Django==1.11. I believe Django 2 tends to suggest using path (or some similarly named function) rather than using url. I don't believe, however, that the semantics of url are different in Django 2, so this is probably an issue for Django 2 users as well.

How to make Django The redirects app higher than urls.py?

Right now i'm using Django The redirects app, but it has some problem.
I can't redirect from url, that have pattern in urls.py
For example i can't redirect from /arsenal1 to any page, because pattern handle it before redirect app.
url(r'^arsenal(?P<arsenal_id>[0-9]+)$', views.arsenal, name='arsenal'),
So, how can i make the high priority to The redirects app?
I can't redirect from url, that have pattern in urls.py
Which is exactly the way it is designed to behave. See this from the doc
The RedirectFallbackMiddleware does all of the work. Each time any
Django application raises a 404 error, this middleware checks the
redirects database for the requested URL as a last resort
Emphasis is mine. the redirect app is only supposed to handle urls that does not exist. Beside why would you possibly want to add an entry in urls.py and then have the redirect app override that?
I think you are probably looking for RedirectView which allows you to define urls in urls.py and have them redirected to various other pages (even dynamically from a database)

Differences between RESTful API and urlpatterns router in Django

Am new to web developpement and wondering the differences between:
Django Restful API
and
standard Django URL routers
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='Index'),
url(r'^getvalue/$', views.get_points, name='Get Points'),
url(r'^putvalue/$', views.put_points, name='Put Points'),
]
What are the benefits of setting Django restful API when interacting with Javascript components since both are JSON sending URL ?
Before understanding this you have know that,
REST API concept.
HTTP verbs(REQUEST METHOD)
REST API
REST API is nothing but very special. Just remember one thing this is a concept where we can use proper use of HTTP VERBS. Like, GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS etc....
HTTP VERBS
I already told you the names of HTTP VERBS. Think what we do normally?? Basically I do, I use POST for updating db row, I use POST for DELETE a row. But in REST API concept we can't do like this kinds of nasty things. When we are going to delete something we need to use DELETE
Links
You may read this, https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
It was quite some time since the question had been asked, but I thought I'd provide an answer as it bothered me as well.
The main reason why you want to use Django's routers is convenience: once you declared them once, you don't have to go through the same cumbersomeness as persistent declaration of urls in urls_patterns.
However, the url_patterns can still be used if for any reason you want to have a specific hard-coded url.

Moving the API Root of Default Router in Django

I'm using Django 1.8 and Django REST Framework. I want the API Root functionality of using a Default Router, but I want to move it to another url, like /apiroot/ or something like that.
I found this post, but it doesn't really answer my question. I don't want to rewrite the API, I basically just want the functionality of the ^$ route to be a standard template page (home page) for the site, and have site.com/apiroot to be the new API root url.
In the process of writing up this question, I looked at the DRF source code, and found my answer. Instead of deleting the question, I figured I'd go ahead and post it, since someone else may be wondering the same thing, and a search hasn't turned up any answers to this already.
The solution to this was to add the following lines to my urls.py:
url(r'^$', media_views.index, name='index'),
url(r'^apiroot/', router.get_api_root_view()),
The first line will replace the ^$ url entry with a pointer to my index method in media_views. The second will mimic the DefaultRouter functionality from / to /apiroot/ and show the API root page there instead.

How are Django page templates assigned to each page?

I couldn't find this info in the Django docs, but I'm sure it is there, I'm just very new and don't know what terms/etc to search on.
How are Django page templates assigned to each page?
I have a login to a Django site, and also SFTP access to the site. I don't think my Django login is a superuser/full-admin though because the interface seems pretty limited compared to other CMS systems. I can edit pages, posts and the media library, but I don't see anything that says how each page is assigned a template.
For example, I have this file /mysite/templates/pages/index.html
I know that template is being used for the home page because it has all of the content that is specific to the home page on it, and changes I make show up on the home page.
I tried copying that file to test.html, but when I browse to test.html in my browser, I get a 404 error (I also get that error if I go to index.html). So there must be something else that maps a template to a page, but I'll be dambed if I can find it. Will I need more access to the admin area, or can I do something with SFTP? I also have SSH access but wasn't able to follow any of the steps online to create a new superuser account for me, for Django.
Edit: Thanks for both answers, after I work through this I'll accept whichever helped the most. I do not have a views.py file, but I think it might be using an extra module for this routing, I have this in my urls.py file:
urlpatterns = patterns("",
("^admin/", include(admin.site.urls)),
url("^$", "mezzanine.pages.views.page", {"slug": "/"}, name="home"),
("^", include("mezzanine.urls")),
)
Is this "mezzanine" something different which changes the answer (location of views.py or list of views)?
url.py is the file that maps the urls to methods that return rendered templates. In essence you define the url and a method and when someone goes to that url, that method gets called which returns a HTTP response with the rendered template. This map is called urlpatterns. In the following example when someone goes to yourwebsite/blog then in the blog apps, view.py, page method is called, which will use a template and render that with specific information.
urlpatterns = patterns('',
url(r'^blog/$', 'blog.views.page'),
url(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
)
Have a look at this link.
https://docs.djangoproject.com/en/dev/topics/http/urls/
Django uses urls.py files to map paths to views. This match is resolved using regular expressions. When a match is found, Django executes the associated view (usually inside views.py). The view is in charge to render the template required for the path (by finding it on the server's hard disk and loading it).
All aforementioned means that there's no direct association between a url path (i.e www.example.com/path/to/page) and a file on the server's hard disk (i.e /server/path/to/page). It's all performed dynamically by Django's engine when a request comes in.
If you want to know which view is gonna be generated for a specific path, follow the regexs at urls.py until you find the path you're looking for. Then open the view for that url and see inside which template it is rendering.
Reading doc's URL Dispatcher is a good point to start learning about this.
Hope this helps!