Proposal or discussion: Add subclasses for No Content and Created HttpResponses

Hi, I just created this ticket for creating HttpResponse subclasses for No Content and Created HTTP responses, which are oftentimes used when creating ‘Restful’ responses.

It got closed because it was discussed earlier in #3362 (Add HttpResponseNoContent response type) – Django (18 years ago!!) and also on this more recent forum thread, which actually is not about HttpResponses but about JsonResponses → [Proposal] Custom JsonResponse Status Classes

The reason given is:

For self-documenting/readable status codes, the advice is to use the HTTPStatus ​enum from python.

I understand that it’s possible to create your own HttpResponse subclasses. But we already DO have many subclasses of HttpResponse: for instance HttpResponseBadRequest, HttpResponseNotFound, HttpResponseNotModified and so on.

So in my opinion it would be consistent to have also HttpResponseNoContent and HttpResponseCreated. There is no good reason we don’t have them, it’s just that their use is a little more recent than Django and than the NotFound 404 response. I think it’s arbitrary that HttpResponseBadRequest is there, but HttpResponseCreated is not. As a hyperbole, just for the discussion: If the preferred way is to create your own response subclass, should we then also mark the HttpResponseNotFound and HttpResponseBadRequest subclass as deprecated and suggest people just subclass HttpResponse in their own code?

I think, for consistency reasons, it would be good to have these HttpResponse subclasses for No Content (204) and Created (201) included in Django. I know my PR has been closed, but I would like to ask to reconsider it.

I don’t think adding further class here is the way to go. Either set the status code when creating the response or create a subclass in your project if that’s what you need.

These are pretty niche responses. There are many codes that don’t have custom classes, and we’re not in the market of adding them all here. (If we were starting now, I’m not sure we’d have the custom classes at all …)

Thanks for your reply. I think Created and NoContent are no ‘niche’ responses. When using Django for REST or AJAXy stuff, which lots of people are using Django for these days, these are the response codes that you would use. Of course you can subclass, but why is there HttpResponseGone but not HttpResponseCreated? It feels arbitrary and inconsistent to me.

Also, one of the reasons I think it might be good to have them in Django is that then there is one place where as a developer you can read about the different responses with a little text about when to use what, which is helpful when choosing the right response → Request and response objects | Django documentation | Django

Yes. And this topic had come up a few times already, but the consensus has been to prefer Python’s HTTPStatus — the response docs even point to that.

I’m not sure I understand where the difference of opinion lies?

Wouldn’t it be possible to create a HTTPNoContent subclass that also uses Python’s HTTPStatus (instead of just 204 as a number)?

In this case, should we maybe consider also migrating other pre-existing response-types to HTTPStatus. Are there any downside? This does look rather backwards compatible to me but maybe I’m overlooking something.

Regarding the niche aspect of those responses, I would tend to agree that both are often used for AJAX (including but not limited to HTMX) and REST, although, I’m told people tend to not do REST with Django outside of DRF and Django Ninja?

It would certainly be possible. It’s adding them at all that the objection is to (and has been in previous iterations of this discussion).

Rough recap of points made ≈ Classes are harder to remember than just using the status code directly, extra surface area, extra docs, and all the rest of it, for very little (to zero) benefit.

Should we the, for the sake of consistency, move this to a new :thread: Deprecate specific HTTPResponse classes that only exist for their status code?

I think that’s not needed. My proposal of removing those subclasses was only made for the sake of the argument! Because I think there IS a good reason to have those and my proposal was to have the Created and NoContent subclasses as well.

Also, some subclasses do add more functionality or sane defaults; for instance the 204 No Content response can’t have response data as per the RFC, otherwise it’s an invalid HTTP request. So the HTTPNoContent subclass in my PR 19203 removed any content type and would error if any content was set. So in this case it’s not just syntactic sugar, it also helps enforce correctness of Django HTTP responses.

This is the same for the HTTP 304 Not Modified response, this will also error out if there is accidently content set.

And it would be VERY confusing if we would deprecate the HttpResponseBadRequest (400) and HttpResponseNotFound (404) because they ‘only exist for their status code’ but we would keep the HttpResponseNotAllowed because it does a little magic.

To be honest, I would also be more in favour of removing these classes than adding more.

I just don’t think that’s worth the churn… Forcing all manner of code to update for basically nothing. I would leave the existing classes as they are, but not add more.

Aside: We need to find a way to log these topics so they’re findable again. This one — as well as others — has been through the wringer a number of times over the years… (It’s hard staying positive repeating the same half-remembered points.)

Discourse does mention similar threads when starting a topic, but ideally related threads would be linked automatically somehow (like Stack Overflow’s related threads on the side). :thinking:

In the past it’s relied on Tim (G) linking past discussions, but that’s not sustainable.

2 Likes

Aside: We need to find a way to log these topics so they’re findable again. This one — as well as others — has been through the wringer a number of times over the years… (It’s hard staying positive repeating the same half-remembered points.)

I have been pondering this too. My initial thought would be to lock a discussion and have a separate area of the forum which would catalog these discussions and perhaps allow for some light editing in the original post as a summary.

1 Like