DeprecationWarning: Request.is_xhr is deprecated. Given that the
X-Requested-With header is not a part of any spec, it is not reliable
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0i-p0ZxBj-fSheGs-2pMXH7K7Oka%3DCjy1YXx-emBu3mw%40mail.gmail.com.
In my opinion there are not many good reasons to have to change behaviour if a request is made via XHR. I think the most common usage is to have a single view that returns a JSON response or a HTML response depending on if XHR is used (https://github.com/search?l=Python&q=request.is_ajax&type=Code), which isn’t great and isn’t reliable.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/84DCD242-69A8-4B8D-9EB6-243312B5F77F%40tomforb.es.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM12ozNou4y6s-AktSwnMfBLDR5FJjYAw-n0kofZ3%3DYtoA%40mail.gmail.com.
Right - Flask's error message also points to something I was mistaken about. XMLHttpRequest does not set this header. jQuery adds it ( https://api.jquery.com/jquery.ajax/#jQuery-ajax-settings ), and presumably some other JS libraries.In my opinion there are not many good reasons to have to change behaviour if a request is made via XHR. I think the most common usage is to have a single view that returns a JSON response or a HTML response depending on if XHR is used (https://github.com/search?l=Python&q=request.is_ajax&type=Code), which isn’t great and isn’t reliable.Riight too. A better way would be to check the Accept header. DRF does this: https://www.django-rest-framework.org/api-guide/content-negotiation/ . Django doesn't provide any tools at the moment for parsing Accept. We could add an API like https://pypi.org/project/django-accept-header/ ?
On Sat, 16 Nov 2019 at 16:16, Tom Forbes <t...@tomforb.es> wrote:
I would agree. Flask has done the same:
DeprecationWarning: Request.is_xhr is deprecated. Given that the X-Requested-With header is not a part of any spec, it is not reliable
In my opinion there are not many good reasons to have to change behaviour if a request is made via XHR. I think the most common usage is to have a single view that returns a JSON response or a HTML response depending on if XHR is used (https://github.com/search?l=Python&q=request.is_ajax&type=Code), which isn’t great and isn’t reliable.
On 16 Nov 2019, at 16:08, Adam Johnson <m...@adamj.eu> wrote:
Django's HttpRequest.is_ajax method determines whether the request was made with the JS API XMLHttpRequest https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.HttpRequest.is_ajax . It does so by checking the X-Requested-With header.The new way of making "AJAX" requests from the browser is the JavaScript fetch() API : https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API .I think the is_ajax() documentation is at least a little misleading in pretending XMLHttpRequest is the only JS API. There also aren't any special headers set by fetch() so it's not possible to detect its requests.I propose deprecating is_ajax() with no replacement.Thoughts?
--Adam--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-d...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0i-p0ZxBj-fSheGs-2pMXH7K7Oka%3DCjy1YXx-emBu3mw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-d...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/84DCD242-69A8-4B8D-9EB6-243312B5F77F%40tomforb.es.
--Adam
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/7aff16cc-aeff-4b5e-b402-e4d587bc9315%40googlegroups.com.
“In my opinion there are not many good reasons to have to change behaviour if a request is made via XHR. I think the most common usage is to have a single view that returns a JSON response or a HTML response depending on if XHR is used (https://github.com/search?l=Python&q=request.is_ajax&type=Code), which isn’t great and isn’t reliable.”
I do this. What would the best way to handle this? Perhaps the proper practice should be documented when it is deprecated?
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/84DCD242-69A8-4B8D-9EB6-243312B5F77F%40tomforb.es.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/cb12b0005c5e4191be3a97d0d2c44cc5%40iss2.ISS.LOCAL.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/DA72EC9C-AE24-4C04-854A-A6E19DD64132%40tomforb.es.
Sorry for barging in like this, but this is actually a problem I have been dealing with quite a bit lately, so:
In my work I very often have to decide, depending on what's calling, what the rendered output might be. Ultimately I went with DRF and its content negotiation, though even that one - as implemented - sometimes isn't sufficient.
See, the problem sometimes isn't that you request JSON and then
get JSON, request HTML and get HTML. You also have to cater for
exceptions. Maybe a 4xx would return additional objects to insert
into the DOM while a 200 would be fine with a JSON or even without
data. What about 500?
I'm currently handling this with custom headers and the caller
(the browser) tells the server what kind of outputs it can handle
in different types of output.
The server then performs the branching at certain code points, specifically the ones mentioned above. DRF allows me to choose the appropriate renderer. Though I should mention here, that the data is already serialised at that point: sometimes this creates issues for renderers that might desire more information to do their work. Just mentioning that render stages need to be accounted for too. This may not be a problem for core Django as it doesn't have stages.
Again, sorry, but still hoping this helped in some way.
LP,
Jure
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CA%2BFDnh%2B5xr1fWteL6bh2NhF0yJV%3DPwyvhkiLYyPmGO23q0sZ9w%40mail.gmail.com.
Sorry for barging in like this, but this is actually a problem I have been dealing with quite a bit lately, so:
In my work I very often have to decide, depending on what's calling, what the rendered output might be. Ultimately I went with DRF and its content negotiation, though even that one - as implemented - sometimes isn't sufficient.
See, the problem sometimes isn't that you request JSON and then get JSON, request HTML and get HTML.
You also have to cater for exceptions. Maybe a 4xx would return additional objects to insert into the DOM while a 200 would be fine with a JSON or even without data. What about 500?
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/0174a0b6-3a32-5339-9ae9-31050d2d2aaf%40gmail.com.
On Tue, Nov 19, 2019 at 1:29 PM Jure Erznožnik <jure.er...@gmail.com> wrote:Sorry for barging in like this, but this is actually a problem I have been dealing with quite a bit lately, so:
In my work I very often have to decide, depending on what's calling, what the rendered output might be. Ultimately I went with DRF and its content negotiation, though even that one - as implemented - sometimes isn't sufficient.
See, the problem sometimes isn't that you request JSON and then get JSON, request HTML and get HTML.
I think content negotiation is about giving the option to request the content in different formats, not rendering different content based on which format is requested.You also have to cater for exceptions. Maybe a 4xx would return additional objects to insert into the DOM while a 200 would be fine with a JSON or even without data. What about 500?
This (and below) is about how to design a particular API for your needs, I think it is out of the scope of the problem discussed. The problem discussed is that is_ajax is not a reliable way to determine the origin of a request (and then format the content of a response)
Agree.
I understood that the discussion already turned to "If
it is deprecated, then the question that arises naturally is
"What would be the proper/new way of doing it?"".
Also, to clarify:
What I wrote wasn't trying to impose a particular solution. I was
just hoping to point out the challenges involved.
LP,
Jure
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CA%2BFDnhKT0ST76G5T6qFz7NWuhnuwoQvqQ3RRHZcFWhyV1jO1sQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/DA72EC9C-AE24-4C04-854A-A6E19DD64132%40tomforb.es.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/260544c2-1dcd-c38f-c267-e4941d1f5088%40gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/827feb18-49c0-44cd-81c6-d2fd6e83c3da%40www.fastmail.com.
> If Django were to provide a solid API for parsing Accept headers [not as easy as it sounds] and selecting a preferred response type [based on accept preference weights] ... would that take care of the bulk of "content negotiation”?> I could imagine a view progressing past the boiler plate [verifying the target object exists, etc], doing its "work", then checking what response form to use, and branching there.I had a look at how DRF handles parses Accept headers, and it honestly doesn’t look too tricky: https://github.com/encode/django-rest-framework/blob/39876e66070c1d6f97740789d5c6f6a0a3ea06cf/rest_framework/utils/mediatypes.py#L52-L62. The precedence logic is a bit complex, but all in all it’s under ~30 lines of actual implementation code.
But providing the ability to parse accept headers and branch is simple enough to match a lot of the current “is_ajax” usages without too many changes. I don’t see much value in trying to tackle more complex/structured content negotiation handing.
Yeah, I expected DRF had this "solved" already. From my own experimentation, mapping `cgi.parse_header` over the the "Accept" header value, split by comma, gets a usable result; then sort that list by 'q' (defaulting to 1.0) and you have your priority.
In the case of content negotiation - https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation - this is only about media types (Accept-Language is already parsed in i18n).
Just parsing them it and make them available in the request - filtered by the supported ones - as an ordered list ("accepted_media_types") and the preferred one ("preferred_media_type") seems sufficient to me.
For functional views, it would be up to you to decide which one you support and how it is delivered with something like "if 'json' in request.preferred_media_type:". We can add decorators for setting the response type for a specific media type and optionally returning a 406.
For CBVs, a mixin should be done - something like ContentNegotiationMixin - where you define the the types you want to support in it (or otherwise use the settings) and you should define or override methods like "to_JSON", "to_XML", "to_LABEL" that will serialize your context into the media type that is the best match for your options.
As more than one media type may correspond to one format, if a dict that labels the supported types is defined, something like:
SUPPORTED_MEDIA_TYPES_LABELS = {
"application/json": "JSON",
"text/json": "JSON",
"application/pdf": "PDF",
"text/html": "HTML",
}
All the filtering can be easily done.
DeprecationWarning: Request.is_ajax is deprecated. Given that the
X-Requested-With header is not a part of any spec, it is not reliable. If you are doing content negotiation, see ..docs/media_type_negotiation. If you are serving different content if the requests are made via AJAX, choose a convention for *your* project to discern them or consider refactoring your code (making your views specific to one intent for each verb).
If you agree - in general - with this direction, I can find time to implement it.
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAL13Cg9x9ZWM0LTLoMMF%3DxgMydqrOKhEnhsRn-miFkVk5Rx6tg%40mail.gmail.com.
If possible, could the logic determining "the best match for your
options" be overridable?
That way standard implementation would cater for 80/20 and
everyone would still have an option to customise further.
LP,
Jure
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CA%2BFDnhKbzzst8PxCr8q26UfYzLAZKi6fqQV9nUjpotkFb%2Byo1w%40mail.gmail.com.
If possible, could the logic determining "the best match for your options" be overridable?
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/9c3dd791-bed0-6c73-d40a-0462c4e93a1a%40gmail.com.