# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from django.forms import widgets
from django.template import loader, Context
from django.utils.encoding import force_text
from rapid.wrappers import ModelData
_templates_root = 'rapid/widgets/'
class RapidReadOnly(widgets.Widget):
def render(self, name, value, attrs=None):
hidden = ''
return '%s%s\n' % (force_text(value), hidden)
def value_from_datadict(self, data, files, name):
return data.get(name)
def getRapidReadonlyRelation(model, originator):
class RapidRelationReadOnly(widgets.Widget):
def render(self, name, value, attrs=None):
hidden = ''
if hasattr(value, '__iter__'):
obj = model.default_manager().filter(pk__in=value)
ret = ''
for o in obj:
ret += '%s\n' % force_text(o)
ret += hidden
return ret
else:
if value:
obj = model.default_manager().get(pk=value)
else:
obj = ""
return '%s%s\n' % (force_text(obj), hidden)
def value_from_datadict(self, data, files, name):
return originator
return RapidRelationReadOnly
class RapidSelector(widgets.Select):
"""
Selects one of the target crud type.
For ForeignKeyFields and OneToOneFields.
If the target is dependent (that means, has only
value when linked with this object), only displays
an edition link.
"""
def __init__(self, relation, *args, **kwargs):
super(RapidSelector, self).__init__(*args, **kwargs)
self.relation = relation
self.allow_multiple_selected = relation.is_multiple()
self.remove_deselected = relation.is_existential_dependency()
def render(self, name, value, attrs=None, choices=()):
tp_id = attrs.get('id', name)
related = self.relation.related_model()
if self.allow_multiple_selected:
if value:
v = ",".join([str(x) for x in value])
selected = related.default_manager().filter(pk__in=value)
else:
v = ""
selected = []
else:
if value:
v = str(value)
selected = related.default_manager().get(pk=value)
else:
v = ""
selected = ""
select_url = related.select_url()
if self.allow_multiple_selected:
icon = 'fa-times'
if self.remove_deselected:
icon = 'fa-trash-o'
else:
icon = 'fa-search'
c = Context({'id': tp_id, 'name': name, 'value': v, 'selected': selected, 'icon': icon,
'select_url': select_url, 'multiple': self.allow_multiple_selected})
if self.allow_multiple_selected:
t = loader.get_template(_templates_root + 'multiple-selector.html')
else:
t = loader.get_template(_templates_root + 'single-selector.html')
return t.render(c)
def value_from_datadict(self, data, files, name):
val = data.get(name)
if self.allow_multiple_selected:
if val:
return [int(x) for x in val.split(",") if x]
return []
else:
if val:
return int(val)
return None
def rapid_alternatives_widget(alternatives, selector):
class RapidAlternativeFormsWidget(widgets.Widget):
def render(self, name, value, attrs=None):
attrs = attrs if attrs else []
c = Context({'name': name,
'value': value,
'attrs': attrs,
'alternatives': alternatives.values(),
'selector': selector,
})
t = loader.get_template(_templates_root + 'alternativeForms.html')
return t.render(c)
def value_from_datadict(self, data, files, name):
ct_id = data.get(selector)
if not ct_id:
return None
return alternatives.get(int(ct_id))[1]
return RapidAlternativeFormsWidget
def rapid_dependent_widget(model_data, form, has_instance, is_mutiple):
class RapidDependentWidget(widgets.Widget):
# What to ask:
# Is it optional? Yep, if it's dependent, it must be optional
# Is it multiple? In is_multiple
def render(self, name, value, attrs=None):
attrs = attrs if attrs else []
c = Context({'name': name,
'value': value,
'attrs': attrs,
'model': model_data,
'formset': form,
}) if is_mutiple else Context (
{'name': name,
'value': value,
'attrs': attrs,
'model': model_data,
'form': form,
'present': has_instance,
})
t = loader.get_template(_templates_root + ('multipleDependent.html' if
is_mutiple else 'singleDependent.html'))
return t.render(c)
def value_from_datadict(self, data, files, name):
# Might return:
# None of model object if not is_multiple
# [] ot list of model objects if is_multiple
if is_mutiple:
list_includes = [x for x in range(0, len(form)) if data.get("includes_" + form.prefix + "-" + str(x))]
return (form, list_includes)
else:
s = data.get("includes_" + name)
if s is None:
return None
else:
return form
return RapidDependentWidget