"""erecord_cmn.views_mixins
Mixins common to erecord applications views
"""
from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework_yaml.renderers import YAMLRenderer
from rest_framework_xml.renderers import XMLRenderer
from rest_framework.renderers import TemplateHTMLRenderer
from erecord_cmn.forms import ErrorForm
from erecord_cmn.serializers import getKeyOptionValues
from erecord_cmn.serializers import FormatOptionSerializer
# Some mixins common to erecord applications views
[docs]class RenderViewMixin(object):
"""additional method about formats .api, .json, .yaml, .xml"""
[docs] def get_renderers( self ):
""" indice 0 for 'json', 1 for 'api', 2 for 'yaml', 3 for 'xml'
(and 4 for 'html' if defined later on)
"""
return [ JSONRenderer(), BrowsableAPIRenderer(),
YAMLRenderer(), XMLRenderer(), ]
[docs]class ListViewMixin(RenderViewMixin):
"""additional methods for views about list
formats .api, .html, .json, .yaml
"""
[docs] def get_renderers( self ):
r = super(ListViewMixin, self).get_renderers()
renderer = TemplateHTMLRenderer()
renderer.template_name='erecord_cmn/headedform_list.html'
r.append( renderer )
return r
[docs]class DetailViewMixin(RenderViewMixin):
"""additional methods for views about detail
formats .html and .api, .json, .yaml, .xml
"""
[docs] def get_renderers( self ):
r = super(DetailViewMixin, self).get_renderers()
renderer = TemplateHTMLRenderer()
renderer.template_name='erecord_cmn/headedform_detail.html'
r.append( renderer )
return r
[docs] def get_specific_renderers( self, template_name ):
r = super(DetailViewMixin, self).get_renderers()
renderer = TemplateHTMLRenderer()
renderer.template_name = template_name
r.append( renderer )
return r
[docs]class DataViewMixin(object):
"""additional methods for views managing both GET and POST requests"""
[docs] def request_query_params(self, request):
return request.query_params
[docs] def request_data(self, request):
#return request.DATA # request.data (cf problem of truncation)
return request.data # request.DATA deprecated ... but previously :
# problem of truncation with request.data
[docs] def data_from_request(self, request):
if request.method == 'POST' :
data = self.request_data(request)
else : # 'GET'
data = self.request_query_params(request)
return data
[docs]class ErrorViewMixin(object):
"""additional methods for views returning error response"""
[docs] def html_error_context(self, detail, status):
""" builds and returns the html context relative to an error"""
context = dict()
error_form = ErrorForm({'status':status, 'detail':detail})
context['error_form'] = error_form
return context
[docs]class ModeOptionViewMixin(object):
"""additional methods for views having mode option
The 'mode' option is used for different choices. Some of them may not \
be available in some calling/view cases. Some may be incompatible each \
other.
The class has been completed in order to also accept some other intuitive \
option names : 'style', 'plan', 'restype'.
@include erecord_cmn/docs/mode_option.txt
(for more information, see the online documentation, main page)
"""
[docs] def get_mode_option_values(self, data):
"""Option 'mode' (several values are possible)
Returns the list of mode option values.
The 'mode' option is used for different choices. Some of them may not \
be available in some calling/view cases. Some may be incompatible \
each other.
The method has been completed in order to also accept, instead of \
'mode' name, some other intuitive option names : 'style', 'plan', \
'restype'.
"""
available_values = [ 'tree', 'link', 'compact', 'compactlist', # style
'single', 'linear', # plan
'dataframe', 'matrix', # restype
'todownload', # todownload
'storage', # storage
'bycol', # bycol
]
s = getKeyOptionValues(data=data, key='style')
s_style = list()
for v in ['tree', 'link', 'compact', 'compactlist'] :
if v in s :
s_style.append(v)
s = getKeyOptionValues(data=data, key='plan')
s_plan = list()
for v in ['single', 'linear']:
if v in s :
s_plan.append(v)
s = getKeyOptionValues(data=data, key='restype')
s_restype = list()
for v in ['dataframe', 'matrix']:
if v in s :
s_restype.append(v)
s = getKeyOptionValues(data=data, key='mode') + s_style + s_plan + s_restype
mode_option = list()
if len(s) > 0:
for v in available_values :
if v in s :
mode_option.append(v)
return mode_option
[docs] def get_plan_value(self, data):
"""returns the plan value according to data
plan = single, linear. Default value : single.
"""
mode_options = self.get_mode_option_values(data=data)
plan = 'single' # default
if mode_options is not None :
if 'linear' in mode_options :
plan = 'linear'
#elif 'single' in mode_options :
# plan = 'single'
return plan
[docs] def get_restype_value(self, data):
"""returns the restype value according to data
restype = dataframe, matrix. Default value : dataframe.
"""
mode_options = self.get_mode_option_values(data=data)
restype = 'dataframe' # default
if mode_options is not None :
if 'matrix' in mode_options :
restype = 'matrix'
#elif 'dataframe' in mode_options :
# restype = 'dataframe'
return restype
[docs] def get_todownload_value(self, data):
"""returns the todownload value according to data
todownload = True, False. Default value : False.
"""
mode_options = self.get_mode_option_values(data=data)
todownload = False # default
if mode_options is not None :
if 'todownload' in mode_options :
todownload = True
return todownload
[docs] def get_storage_value(self, data):
"""returns the storage value according to data
storage = True, False. Default value : False.
"""
mode_options = self.get_mode_option_values(data=data)
storage = False # default
if mode_options is not None :
if 'storage' in mode_options :
storage = True
return storage
[docs] def get_bycol_value(self, data):
"""returns the bycol value according to data
bycol = True, False. Default value : False.
"""
mode_options = self.get_mode_option_values(data=data)
bycol = False # default
if mode_options is not None :
if 'bycol' in mode_options :
bycol = True
return bycol
[docs]class DataFolderCopyViewMixin(object):
"""additional methods for views having datafoldercopy option """
[docs] def get_datafoldercopy_value(self, data):
"""returns the datafoldercopy value according to data
datafoldercopy = replace, overwrite. Default value : replace.
"""
s = getKeyOptionValues(data=data, key='datafoldercopy')
datafoldercopy = 'replace' # default
if 'overwrite' in s and 'replace' not in s :
datafoldercopy = 'overwrite'
return datafoldercopy
[docs]class StyleViewMixin(ModeOptionViewMixin):
"""additional methods for views having style (in mode option)
style = tree or link
"""
[docs] def get_style_value( self ):
"""returns the style value according to data
style = tree or link. Default value : tree.
"""
mode_options = self.get_mode_option_values(
data=self.request.query_params)
style = 'tree' # default
if mode_options is not None :
if 'link' in mode_options :
style = 'link'
return style
[docs] def get_serializer_class_style(self, serializer_tree_class,
serializer_link_class):
""" returns the serializer class corresponding with style value """
style = self.get_style_value()
if style == 'link' :
return serializer_link_class
else : # 'tree'
return serializer_tree_class
[docs]class DataListViewMixin(RenderViewMixin):
"""additional methods for views returning a list of datas """
[docs] def get_renderers( self ):
r = RenderViewMixin.get_renderers(self)
renderer = TemplateHTMLRenderer()
renderer.template_name='erecord_cmn/headedform_data_list.html'
r.append( renderer )
return r