#20643 closed Bug (fixed)
Examples in Chapter Using mixins with class-based views
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | bmispelon@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I tried to use following examples:
https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/
import json from django.http import HttpResponse class JSONResponseMixin(object): response_class = HttpResponse def render_to_response(self, context, **response_kwargs): response_kwargs['content_type'] = 'application/json' return self.response_class( self.convert_context_to_json(context), **response_kwargs ) def convert_context_to_json(self, context): return json.dumps(context) from django.views.generic.detail import SingleObjectTemplateResponseMixin class HybridDetailView(JSONResponseMixin, SingleObjectTemplateResponseMixin, BaseDetailView): def render_to_response(self, context): # Look for a 'format=json' GET argument if self.request.GET.get('format','html') == 'json': return JSONResponseMixin.render_to_response(self, context) else: return SingleObjectTemplateResponseMixin.render_to_response(self, context)
It seems to me, that attribute response_class = HttpResponse in JSONReponseMixin overlaps attribute response_class = TemplateResponse in TemplateResponseMixin (and SingleObjectTemplateResponseMixin) and breaks non-json requests.
Following code works but doesn't look like proper solution to me:
import json from django.http import HttpResponse class JSONResponseMixin(object): def render_to_response(self, context, **response_kwargs): response_kwargs['content_type'] = 'application/json' return HttpResponse( self.convert_context_to_json(context), **response_kwargs ) def convert_context_to_json(self, context): return json.dumps(context)
Michal
Attachments (1)
Change History (7)
comment:1 by , 11 years ago
Cc: | added |
---|---|
Has patch: | set |
Triage Stage: | Unreviewed → Accepted |
by , 11 years ago
Attachment: | ticket-20643.patch added |
---|
follow-up: 6 comment:2 by , 11 years ago
Btw, is there any reason to write:
class HybridDetailView(JSONResponseMixin, SingleObjectTemplateResponseMixin, BaseDetailView):
Instead of :
class HybridDetailView(JSONResponseMixin, DetailView):
Other than that, I'm happy with the fix.
follow-up: 4 comment:3 by , 11 years ago
I have two suggestions.
Would it be possible to mention somewhere in the docs (chapter Using Django/Class-based views or API Reference/Class-based views) following site? It's extremely useful for everyone working with class-based views:
http://ccbv.co.uk/
It would be also nice to mention some tips how to handle the conversion of context to json. For example model_to_dict method can be useful when processing single objects:
from django.forms.models import model_to_dict ... def convert_context_to_json(self, context): return json.dumps(model_to_dict(context['object']))
Or we can show some custom JSON encoders for handling datetime.date objects etc.
comment:4 by , 11 years ago
I forgot to login before sending my previous comment...
Here is an article showing another way of model to dictionary conversion:
http://www.pythondiary.com/tutorials/django-and-ajax-jquery.html
Replying to anonymous:
I have two suggestions.
Would it be possible to mention somewhere in the docs (chapter Using Django/Class-based views or API Reference/Class-based views) following site? It's extremely useful for everyone working with class-based views:
http://ccbv.co.uk/
It would be also nice to mention some tips how to handle the conversion of context to json. For example model_to_dict method can be useful when processing single objects:
from django.forms.models import model_to_dict ... def convert_context_to_json(self, context): return json.dumps(model_to_dict(context['object']))Or we can show some custom JSON encoders for handling datetime.date objects etc.
comment:5 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:6 by , 11 years ago
(to loic84)
You're right, since DetailView
inherits from SingleObjectTemplateResponseMixin
and BaseDetailView
, we could switch the two.
I suspect this was done to show that the view was made of two *ResponseMixin
, without having to spend time explaining the inheritance chain of DetailView
.
However, I think it works fine this way, so I decided not to change it.
(to msladek)
I decided against adding a link to ccbv.co.uk.
While I agree that this tool is very useful, I'd rather see Django's documentation be improved than having to rely on external tools to compensate.
I did however add a note linking to the documentation that explains how to serialize django models properly [1].
Thanks to both of you.
[1] https://docs.djangoproject.com/en/1.5/topics/serialization/
Hi,
Thanks for catching this. I actually fixed up a bunch of similar mistakes in the CBV topic docs yesterday but I missed this one.
I think the way that
JSONResponseMixin
is written makes it so that it's hard to implementHybridDetailview
correctly.The solution you propose doesn't seem so bad to me.
The idea is to keep
JSONResponseMixin.render_to_response
self-contained so that it can be more easily mixed-in without interfering too much.I would actually go one step further and remove
render_to_response
fromJSONResponseMixin
in favor of a dedicatedrender_to_json_response
method (see attached path), making it the view's responsability to call the prefered rendering method.It makes things a bit more verbose and the documentation needs to be changed quite a bit more, but I think it makes things a bit cleaner.
What do you think?