- Author:
- danielsokolowski
- Posted:
- August 4, 2011
- Language:
- Python
- Version:
- 1.3
- Score:
- 0 (after 0 ratings)
Adding this mixing to your existing class based views allows for outputting of queries into any registered serialzier format -- very handy for dynamic JS based GUI on the JSON format.
This generic view mixing was created on our last project which required a fancy JS based user experience and yet also needed to be accessible through non JS enabled browsers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | """
Author: Daniel Sokolowski ([email protected])
Generic Views used by the project
"""
from django.http import HttpResponse
from django.core import serializers
from django.views.generic.base import TemplateResponseMixin
from django.http import Http404
from django.core.exceptions import ImproperlyConfigured
class MultiFormatResponseMixin(TemplateResponseMixin):
"""
Render http response in in either in HTML (default), HTML snippet or any serializer that is supported format.
The rendering output is determined by ``output`` request GET variable as follows:
``?output=serialzier_<serializer_name> OR <html> OR <inc.html>`` - OPTIONAL: defaults to html
<serializer_name> part of the GET variable is passed to the Django serialzier frame with additional ``serializer_options``
defined on your custom class views. Hence if one has added additional serialziers they are fully supported.
If <serializer_name> dosen't exist or output serializer format is not supported or serializer_options are missing
a 404 response is generated.
To use simple define your class based view as follows and based on ?output=<value> different format is returned:
```
class AdCategoryListView(MultiFormatResponseMixin, ListView):
context_object_name="adcategories_list"
serializer_options = {
'json': {
'fields': ['locations'],
'extras': ['get_firstmedia_url']
},
'geojson': {
'fields': ['locations'],
}
}
def get_queryset(self):
return AdCategory.objects.filter(parent_category__isnull = True)
...
...
```
Template naming convention for different outputs:
```?output=serialzier_json``` = NO TEMPLATE - response is output of calling json serialzier on the query
```?output=serialzier_foobar``` = NO TEMPLATE - response is output of calling foobar serialzier on the query
```?output=html``` = <templates>/<app_label>/<model name><template_name_suffix>.html
```?output=inc.html``` = <templates>/<app_label>/<model name><template_name_suffix>.inc.html
Suggested aditional serialziers:
GEOJSON - http://djangosnippets.org/snippets/2434/)
DjangoFullSerializers http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers
"""
def render_to_response(self, context):
# Look for a 'format=<foo>' GET argument if dosen't exist then do normal html Template Response mixin response
if self.request.GET.get('output','html') == 'html':
return super(MultiFormatResponseMixin, self).render_to_response(context) # call original ListView.render_to_response()
elif self.request.GET.get('output','') == 'inc.html':
opts = self.get_queryset().model._meta
self.template_name = "%s/%s%s.inc.html" % (opts.app_label, opts.object_name.lower(), self.template_name_suffix)
return super(MultiFormatResponseMixin, self).render_to_response(context) # call original ListView.render_to_response()
output = self.request.GET.get('output')
if not 'serializer_' in output:
raise Http404
"""
Check we are configured properly first - we do the check here so that adding this mixin
dosen't prevent original view logic from executing
"""
if not hasattr(self, 'serializer_options'):
raise ImproperlyConfigured(u"'%s' must define 'serializer_options'" % self.__class__.__name__)
serializer = output.split('_')[1] # grap serialzier name
""" if serialzier is not supported or it's options not specified in view's serializer_options raise 404"""
if not serializer in serializers.get_serializer_formats() or serializer not in self.serializer_options:
raise Http404
output = self.request.GET.get('output','')
query = self.get_queryset()
if hasattr(self, 'get_object'): # if get_object attribute exists than we should filter to that object only
query = query.filter(pk=self.get_object().pk)
content = serializers.serialize(serializer, query, **self.serializer_options[serializer])
#return HttpResponse(content, content_type='application/%s' % serializer)
return HttpResponse(content)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Please login first before commenting.