Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Matemática A3K
On Wed, Nov 20, 2019 at 11:52 PM James Bennett 
wrote:

> On Wed, Nov 20, 2019 at 3:44 PM Curtis Maloney 
> wrote:
>
>>
>> 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.
>>
>
> Both the original and forks seem to've been abandoned now, but the
> mimeparse library encapsulated this into a nice little function that took
> an Accept header, and a list of content-types you could support in the
> response, and told you which one was the best match. The code's still out
> there and under a permissive license if somebody wants to pick it up again.
>

I think now that providing alternatives is the way to go :)

When 'is_ajax' is used for content negotiation, then proper content
negotiation via the Accept headers should be done.

When 'is_ajax' is used for different content delivery (like routing), then
make the convention explicit or refactoring should be done.

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.

If so, the deprecation warning should be something like:
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-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAL13Cg9x9ZWM0LTLoMMF%3DxgMydqrOKhEnhsRn-miFkVk5Rx6tg%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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CA%2BFDnhKbzzst8PxCr8q26UfYzLAZKi6fqQV9nUjpotkFb%2Byo1w%40mail.gmail.com.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Asif Saif Uddin
Not so sure though, but would like to know if 
https://github.com/python-hyper these libraries are of any use for django 
http?

On Thursday, November 21, 2019 at 5:52:12 AM UTC+6, James Bennett wrote:
>
> On Wed, Nov 20, 2019 at 3:44 PM Curtis Maloney  > wrote:
>
>>
>> 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.
>>
>
> Both the original and forks seem to've been abandoned now, but the 
> mimeparse library encapsulated this into a nice little function that took 
> an Accept header, and a list of content-types you could support in the 
> response, and told you which one was the best match. The code's still out 
> there and under a permissive license if somebody wants to pick it up again. 
>

-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/1b5fde50-b61f-42b3-b59d-13c4fa4b5efb%40googlegroups.com.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread James Bennett
On Wed, Nov 20, 2019 at 3:44 PM Curtis Maloney  wrote:

>
> 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.
>

Both the original and forks seem to've been abandoned now, but the
mimeparse library encapsulated this into a nice little function that took
an Accept header, and a list of content-types you could support in the
response, and told you which one was the best match. The code's still out
there and under a permissive license if somebody wants to pick it up again.

-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAL13Cg9x9ZWM0LTLoMMF%3DxgMydqrOKhEnhsRn-miFkVk5Rx6tg%40mail.gmail.com.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Curtis Maloney


On Thu, 21 Nov 2019, at 09:25, Tom Forbes wrote:
> > 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.

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.

But knowing that's the right way to parse Accept headers, and asking for match 
or quality measures of your response options, feel like an abstraction Django 
could/should provide.

> 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.

This was my hope - an 80/20 solution that in no way precluded other solutions.

--
C

-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/519f9b4e-ad9d-4814-ad6f-c6faff809867%40www.fastmail.com.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Tom Forbes
> 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.


> On 20 Nov 2019, at 21:46, Curtis Maloney  wrote:
> 
> My reading of this discussion boils down to "if we get rid of is_ajax (a 
> buy-in convention nobody can rely on), how do people decide if it's an AJAX 
> call or not?". To my mind, the "content negotiation" advocates have it right: 
> HTTP has a mechanism for determining what response format is desired.
> 
> 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.
> 
> --
> Curtis
> 
> 
> On Wed, 20 Nov 2019, at 21:04, Jure Erznožnik wrote:
>> 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
>> 
>> On 20/11/2019 02:17, Matemática A3K wrote:
>>> 
>>> 
>>> On Tue, Nov 19, 2019 at 9:20 PM Matemática A3K >> > wrote:
>>> 
>>> 
>>> On Tue, Nov 19, 2019 at 1:29 PM Jure Erznožnik >> > 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)
>>> 
>>> (let me try to expand myself a bit so we can refocus)
>>> 
>>> If it is deprecated, then the question that arises naturally is "What would 
>>> be the proper/new way of doing it?" because it is a pattern that have been 
>>> applied previously (i.e. 
>>> https://docs.djangoproject.com/en/2.2/topics/class-based-views/generic-editing/#ajax-example
>>>  
>>> ),
>>>  then decorators have been proposed and refactors.
>>> 
>>> It seems to me that if there is no reliable way of determining it from the 
>>> back-end side, then in the end it will be a convention between the front 
>>> and the back. This could be a GET parameter, a "ClientWants: JSONOrNothing" 
>>> header, or whatever convention you like to make, but not rely on a 
>>> convention which seems to be fading out.
>>> 
>>> You can ensure the actual convention by setting the header manually (as 
>>> stated in the is_ajax doc) - as you do with the CSRF token. Another 
>>> convention could be better (i.e. "accepts json")
>>> 
>>> So far, is what the discussion went through to my underst

Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Claude Paroz
Le 20.11.19 à 22:46, Curtis Maloney a écrit :
> My reading of this discussion boils down to "if we get rid of is_ajax (a
> buy-in convention nobody can rely on), how do people decide if it's an
> AJAX call or not?". To my mind, the "content negotiation" advocates have
> it right: HTTP has a mechanism for determining what response format is
> desired.

It doesn't cover all use cases. For example, I have a use case where an
AJAX call only returns a partial HTML snippet while a non-AJAX call is
returning a full HTML page (same content type in both cases)
.
But in that case, I agree with a previous poster that it's a matter of
convention between client and server. I can rather easily create my own
`is_ajax(request)` utility depending on the convention I choose.

Claude
-- 
www.2xlibre.net

-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/53992754-6e8d-b138-a88b-85d4cfc68891%402xlibre.net.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Curtis Maloney
My reading of this discussion boils down to "if we get rid of is_ajax (a buy-in 
convention nobody can rely on), how do people decide if it's an AJAX call or 
not?". To my mind, the "content negotiation" advocates have it right: HTTP has 
a mechanism for determining what response format is desired.

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.

--
Curtis


On Wed, 20 Nov 2019, at 21:04, Jure Erznožnik wrote:
> 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

> On 20/11/2019 02:17, Matemática A3K wrote:
>> 
>> 
>> On Tue, Nov 19, 2019 at 9:20 PM Matemática A3K  
>> wrote:
>>> 
>>> 
>>> On Tue, Nov 19, 2019 at 1:29 PM Jure Erznožnik  
>>> 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)
>> 
>> (let me try to expand myself a bit so we can refocus)
>> 
>> If it is deprecated, then the question that arises naturally is "What would 
>> be the proper/new way of doing it?" because it is a pattern that have been 
>> applied previously (i.e. 
>> https://docs.djangoproject.com/en/2.2/topics/class-based-views/generic-editing/#ajax-example),
>>  then decorators have been proposed and refactors.
>> 
>> It seems to me that if there is no reliable way of determining it from the 
>> back-end side, then in the end it will be a convention between the front and 
>> the back. This could be a GET parameter, a "ClientWants: JSONOrNothing" 
>> header, or whatever convention you like to make, but not rely on a 
>> convention which seems to be fading out.
>> 
>> You can ensure the actual convention by setting the header manually (as 
>> stated in the is_ajax doc) - as you do with the CSRF token. Another 
>> convention could be better (i.e. "accepts json")
>> 
>> So far, is what the discussion went through to my understanding :)
 

 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

 

 On 19/11/2019 01:06, Matemática A3K wrote:
> 
> I agree with Adam that it should be deprecated with no replacement.
> 
> The content negotiation is something that should be in but not as a 
> replacement of it, as a general improvement.
> 
> I think there shouldn't be a replacement because "is_ajax" asks whether 
> it came from a ""regular"" browser instead of jQuery and with the content 
> negotiation you ask if the requester accepts a type - which can also lead 
> to errors because the client may also accept other types (no example 
> coming to my mind), and if so, it will lead to undesired behavior.
> 
> The right appr

Re: The Missing Piece in Indexing

2019-11-20 Thread Adam Johnson
Hi Behzad

Your database will automatically use the appropriate indexes for given
queries, thanks to its optimizer. See
https://en.m.wikipedia.org/wiki/Query_optimization and DB specific docs
such as: https://www.postgresql.org/docs/9.0/planner-optimizer.html ,
https://dev.mysql.com/doc/internals/en/optimizer.html .

USE INDEX is only for forcing usage of particular indexes if you are *sure*
that you know better than your optimizer. You don't need it in 99% of
cases, it's a bit of a sledgehammer, and prone to bitrot into bad
performance if your tables change. However if you're sure you want to do
this, for MySQL/MariaDB, my library Django-MySQL adds a QuerySet extension
for it:
https://django-mysql.readthedocs.io/en/latest/queryset_extensions.html#django_mysql.models.use_index
. I've actually never ended up needing it myself.

Thanks,

Adam

On Wed, 20 Nov 2019 at 08:31, Behzad  wrote:

> Hey all!
>
> I noticed a while ago that we can set indexes in the models Meta as
> described here
> . But
> I can't find any commands on the Queryset which helps us use the declared
> indexes, the equivalent of `USE INDEX` in the DB.
> Is this planned to be developed?
>
> Best
> Behzad
>
> --
> 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-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/e95a9413-1c0f-48b2-ae25-5417c3a742e2%40googlegroups.com
> 
> .
>


-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMyDDM3n9%2ByJNyXezcDuyv1m0WX5fLbUS4ZnTDMRAW7F3tHhkQ%40mail.gmail.com.


The Missing Piece in Indexing

2019-11-20 Thread Behzad
Hey all!

I noticed a while ago that we can set indexes in the models Meta as 
described here 
. But I 
can't find any commands on the Queryset which helps us use the declared 
indexes, the equivalent of `USE INDEX` in the DB.
Is this planned to be developed?

Best
Behzad

-- 
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-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/e95a9413-1c0f-48b2-ae25-5417c3a742e2%40googlegroups.com.


Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Manoj Kiraula
I want ask a question regarding creating a string,why while creating a
string where user give the input,there are different references of that
object

On Mon, Nov 18, 2019, 8:58 PM Tom Forbes  wrote:

> What I meant by that is it’s not an approach that scales well to lots of
> views. It might be better to have separate endpoints to return JSON (e.g
> adding a /json suffix), and in the past this has made services I’ve worked
> on a lot more maintainable and easy to understand. But it’s not as quick to
> do as `if request.is_ajax()` and requires a bit more upfront work. If you
> find you need to do this a lot then maybe something more structured like
> Django Rest Framework will be a better choice, which also handles content
> negotiation really well (it can produce XML, CSV, JSON, etc etc).
>
> On 18 Nov 2019, at 15:18, Matthew Pava  wrote:
>
> “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?
>
> *From:* django-developers@googlegroups.com [
> mailto:django-developers@googlegroups.com
> ] *On Behalf Of *Tom Forbes
> *Sent:* Saturday, November 16, 2019 10:16 AM
> *To:* django-developers@googlegroups.com
> *Subject:* Re: Deprecate HttpRequest.is_ajax
>
> 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  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-developers+unsubscr...@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-developers+unsubscr...@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
> 
> .
>
> --
> 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-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/cb12b0005c5e4191be3a97d0d2c44cc5%40iss2.ISS.LOCAL
> 
> .
>
>
> --
> 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-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visi

Re: Deprecate HttpRequest.is_ajax

2019-11-20 Thread Jure Erznožnik

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

On 20/11/2019 02:17, Matemática A3K wrote:



On Tue, Nov 19, 2019 at 9:20 PM Matemática A3K 
mailto:matematica@gmail.com>> wrote:




On Tue, Nov 19, 2019 at 1:29 PM Jure Erznožnik
mailto:jure.erznoz...@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)


(let me try to expand myself a bit so we can refocus)

If it is deprecated, then the question that arises naturally is "What 
would be the proper/new way of doing it?" because it is a pattern that 
have been applied previously (i.e. 
https://docs.djangoproject.com/en/2.2/topics/class-based-views/generic-editing/#ajax-example), 
then decorators have been proposed and refactors.


It seems to me that if there is no reliable way of determining it from 
the back-end side, then in the end it will be a convention between the 
front and the back. This could be a GET parameter, a "ClientWants: 
JSONOrNothing" header, or whatever convention you like to make, but 
not rely on a convention which seems to be fading out.


You can ensure the actual convention by setting the header manually 
(as stated in the is_ajax doc) - as you do with the CSRF token. 
Another convention could be better (i.e. "accepts json")


So far, is what the discussion went through to my understanding :)

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


On 19/11/2019 01:06, Matemática A3K wrote:


I agree with Adam that it should be deprecated with no
replacement.

The content negotiation is something that should be in but
not as a replacement of it, as a general improvement.

I think there shouldn't be a replacement because "is_ajax"
asks whether it came from a ""regular"" browser instead of
jQuery and with the content negotiation you ask if the
requester accepts a type - which can also lead to errors
because the client may also accept other types (no example
coming to my mind), and if so, it will lead to undesired
behavior.

The right approach would be making AJAX requests request JSON
output explicitly, by using a dedicated endpoint or by
appending something that manifests their intention - like in

https://docs.djangoproject.com/en/2.2/topics/class-based-views/mixins/#more-than-just-html
is done with a get parameter. Not decide the response type by
where it came from as it is unreliable as stated before, it
provides convenience in some use cases but can lead to errors.

Seems better to me to refactor the view code so you can write
a different view for Ajax requests that returns a JSON
without code duplication.

As a shortcut, something like "For simple AJAX endpoints wrap
your view with (