|
@@ -1,351 +1,369 @@
|
|
-# -*- coding: utf-8 -*-
|
|
|
|
-
|
|
|
|
-__author__ = 'marcos.medeiros'
|
|
|
|
-
|
|
|
|
-from rapid.registry import registry, Action
|
|
|
|
-from rapid import filters
|
|
|
|
-
|
|
|
|
-import itertools
|
|
|
|
-from django.db import models
|
|
|
|
-from rapid import permissions
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class InstanceData:
|
|
|
|
- def __init__(self, instance, request=None, excludes=None, creator=None, fields=None):
|
|
|
|
- excludes = [] if excludes is None else excludes
|
|
|
|
- self.model = ModelData(type(instance), request, excludes, creator, fields)
|
|
|
|
- self.instance = instance
|
|
|
|
- self.request = request
|
|
|
|
- self.excludes = excludes if excludes else []
|
|
|
|
- self.creator = creator
|
|
|
|
- self._fields = fields if fields else self.model.fields()
|
|
|
|
-
|
|
|
|
- def values(self):
|
|
|
|
- r = []
|
|
|
|
- o = self.instance
|
|
|
|
- for f in self.model.fields():
|
|
|
|
- if f.is_relation:
|
|
|
|
- r.append(self._value_of_field(o, f))
|
|
|
|
- else:
|
|
|
|
- r.append(self._value_of_field(o, f))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def _value_of_field(self, instance, field):
|
|
|
|
- """
|
|
|
|
- Returns the value of the given field.
|
|
|
|
- ::return A tuple, with the actual value of the field, a boolean that is true iff
|
|
|
|
- the value is iterable, and a sequence of URLs for the viewers of the instances
|
|
|
|
- of the first element, or False if there are no viewers.
|
|
|
|
- """
|
|
|
|
- if hasattr(instance, field.accessor_name()):
|
|
|
|
- v = getattr(instance, field.accessor_name())
|
|
|
|
- else: # Many to many relations without value may disappear
|
|
|
|
- return [], True
|
|
|
|
- if hasattr(v, '__iter__'):
|
|
|
|
- return (v, ()), True
|
|
|
|
- if hasattr(v, 'all'):
|
|
|
|
- return [(x, InstanceData(x, self.request, creator=(self, field))) for x in v.all()], True
|
|
|
|
- if isinstance(v, models.Model):
|
|
|
|
- return (v, InstanceData(v, self.request, creator=(self, field))), False
|
|
|
|
- return (v, ()), False
|
|
|
|
-
|
|
|
|
- def fields_and_values(self):
|
|
|
|
- r = []
|
|
|
|
- for field in self.model.fields():
|
|
|
|
- value, is_multiple = self._value_of_field(self.instance, field)
|
|
|
|
- r.append((field, value, is_multiple))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def is_controlled(self):
|
|
|
|
- return self.model.is_controlled()
|
|
|
|
-
|
|
|
|
- def can_read(self):
|
|
|
|
- return self.has_permission(self.request, 'view')
|
|
|
|
-
|
|
|
|
- def can_write(self):
|
|
|
|
- return self.has_permission(self.request, 'edit')
|
|
|
|
-
|
|
|
|
- def view_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model.model, "view", pk=self.instance.pk)
|
|
|
|
-
|
|
|
|
- def edit_url(self):
|
|
|
|
- url = registry.get_url_of_action(self.model.model, "edit", pk=self.instance.pk)
|
|
|
|
- by = self.creator
|
|
|
|
- if by:
|
|
|
|
- dt, fd = by
|
|
|
|
- if fd.one_to_one or fd.one_to_many:
|
|
|
|
- # Do not change the parent of the viewer.
|
|
|
|
- return url + "?default=" + fd.field.name + ":" + str(dt.object.pk)
|
|
|
|
- if fd.many_to_one or fd.many_to_many:
|
|
|
|
- return url
|
|
|
|
- return url
|
|
|
|
-
|
|
|
|
- def remove_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model.model, "delete", pk=self.instance.pk)
|
|
|
|
-
|
|
|
|
- def create_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model.model, "add")
|
|
|
|
-
|
|
|
|
- def list_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model.model, "list")
|
|
|
|
-
|
|
|
|
- def select_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model.model, "select")
|
|
|
|
-
|
|
|
|
- def actions(self):
|
|
|
|
- r = []
|
|
|
|
- acts = registry.model_entry(self.model.model)
|
|
|
|
- if self.request and acts:
|
|
|
|
- for a in acts.values():
|
|
|
|
- if self.has_permission(self.request, a.action.name) and\
|
|
|
|
- a.action.visibility > Action.Visibility.hidden:
|
|
|
|
- r.append((a, a.get_url(self.instance)))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def model_actions(self):
|
|
|
|
- r = []
|
|
|
|
- for (a, u) in self.actions():
|
|
|
|
- if not a.action.query_parameters:
|
|
|
|
- r.append((a, u))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def instance_actions(self):
|
|
|
|
- r = []
|
|
|
|
- for (a, u) in self.actions():
|
|
|
|
- if a.action.query_parameters:
|
|
|
|
- r.append((a, u))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def list_actions(self):
|
|
|
|
- r = []
|
|
|
|
- for (a, u) in self.instance_actions():
|
|
|
|
- if a.action.visibility == Action.Visibility.list:
|
|
|
|
- r.append((a, u))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def has_permission(self, request, action_name):
|
|
|
|
- m = registry.model_entry(self.model.model).get(action_name)
|
|
|
|
- if m:
|
|
|
|
- perm = m.permission.instances
|
|
|
|
- return permissions.has_instance(self.model, perm(request), self.instance)
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def __unicode__(self):
|
|
|
|
- return unicode(self.instance)
|
|
|
|
-
|
|
|
|
- def __str__(self):
|
|
|
|
- return str(self.model) + ': ' + str(self.instance.pk)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class ModelData:
|
|
|
|
- def __init__(self, model, request=None, excludes=None, creator=None, fields=None):
|
|
|
|
- excludes = [] if excludes is None else excludes
|
|
|
|
- self.model = model
|
|
|
|
- self.request = request
|
|
|
|
- self.excludes = excludes if excludes else []
|
|
|
|
- self.creator = creator
|
|
|
|
- self._fields = [self.field_by_name(f) for f in fields] if fields else self.all_fields()
|
|
|
|
-
|
|
|
|
- def model_name(self):
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- return unicode(self.model._meta.verbose_name)
|
|
|
|
-
|
|
|
|
- def model_name_plural(self):
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- return unicode(self.model._meta.verbose_name_plural)
|
|
|
|
-
|
|
|
|
- def default_manager(self):
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- return self.model._default_manager
|
|
|
|
-
|
|
|
|
- def all_fields(self):
|
|
|
|
- r = []
|
|
|
|
- relations = []
|
|
|
|
- for f in itertools.chain(self.local_fields(), self.related_fields()):
|
|
|
|
- if f.is_relation():
|
|
|
|
- relations.append(f)
|
|
|
|
- else:
|
|
|
|
- if f.name not in self.excludes:
|
|
|
|
- r.append(f)
|
|
|
|
- for f in relations:
|
|
|
|
- if f.name not in self.excludes:
|
|
|
|
- r.append(f)
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def fields(self):
|
|
|
|
- return self._fields
|
|
|
|
-
|
|
|
|
- def local_fields(self):
|
|
|
|
- r = []
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- for f in self.model._meta.local_fields:
|
|
|
|
- if f.name not in self.excludes:
|
|
|
|
- r.append(FieldData(f, self.request))
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- for f in self.model._meta.local_many_to_many:
|
|
|
|
- if f.name not in self.excludes:
|
|
|
|
- r.append(FieldData(f, self.request))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def related_fields(self):
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- return [FieldData(f, self.request) for f in self.model._meta.get_all_related_objects()]
|
|
|
|
-
|
|
|
|
- def is_controlled(self):
|
|
|
|
- return registry.is_controlled(self.model)
|
|
|
|
-
|
|
|
|
- def can_read(self):
|
|
|
|
- if self.can_write():
|
|
|
|
- return True
|
|
|
|
- vw = registry.model_entry(self.model)['view'].permission(self.request)
|
|
|
|
- if vw:
|
|
|
|
- return vw.exists()
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def can_write(self):
|
|
|
|
- ed = registry.model_entry(self.model)['edit'].permission(self.request)
|
|
|
|
- if ed:
|
|
|
|
- return ed.exists()
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def create_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model, "add")
|
|
|
|
-
|
|
|
|
- def list_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model, "list")
|
|
|
|
-
|
|
|
|
- def select_url(self):
|
|
|
|
- return registry.get_url_of_action(self.model, "select")
|
|
|
|
-
|
|
|
|
- def actions(self):
|
|
|
|
- r = []
|
|
|
|
- acts = registry.model_entry(self.model)
|
|
|
|
- if self.request and acts:
|
|
|
|
- for a in acts.values():
|
|
|
|
- if self.has_permission(self.request, a.action.name) and\
|
|
|
|
- not a.action.query_parameters and\
|
|
|
|
- a.action.visibility > Action.Visibility.hidden:
|
|
|
|
- r.append((a, a.get_url()))
|
|
|
|
- return r
|
|
|
|
-
|
|
|
|
- def has_permission(self, request, action_name):
|
|
|
|
- m = registry.model_entry(self.model).get(action_name)
|
|
|
|
- if m:
|
|
|
|
- return bool(m.permission.model(request))
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def field_by_name(self, field_name):
|
|
|
|
- # noinspection PyProtectedMember
|
|
|
|
- return FieldData(self.model._meta.get_field(field_name), self.request)
|
|
|
|
-
|
|
|
|
- def __unicode__(self):
|
|
|
|
- return unicode(self.model)
|
|
|
|
-
|
|
|
|
- def __str__(self):
|
|
|
|
- return 'Model: ' + str(self.model)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class FieldData:
|
|
|
|
- def __init__(self, field, request=None):
|
|
|
|
- self.field = field
|
|
|
|
- self.request = request
|
|
|
|
-
|
|
|
|
- @classmethod
|
|
|
|
- def from_model(cls, model, field_name):
|
|
|
|
- ff = ModelData(model).fields()
|
|
|
|
- for f in ff:
|
|
|
|
- if f.bare_name() == unicode(field_name):
|
|
|
|
- return f
|
|
|
|
- return None
|
|
|
|
-
|
|
|
|
- def bare_name(self):
|
|
|
|
- return unicode(self.field.name)
|
|
|
|
-
|
|
|
|
- def accessor_name(self):
|
|
|
|
- if hasattr(self.field, 'get_accessor_name'):
|
|
|
|
- return unicode(self.field.get_accessor_name())
|
|
|
|
- return unicode(self.field.name)
|
|
|
|
-
|
|
|
|
- def name(self):
|
|
|
|
- if self.is_auto() and self.is_relation():
|
|
|
|
- return self.related_model().model_name_plural() + u' - ' + self.related_field().name()
|
|
|
|
- if hasattr(self.field, "verbose_name"):
|
|
|
|
- return unicode(self.field.verbose_name)
|
|
|
|
- return unicode(self.field.name)
|
|
|
|
-
|
|
|
|
- def name_plural(self):
|
|
|
|
- if self.is_auto() and self.is_relation():
|
|
|
|
- return self.related_model().model_name_plural() + u' - ' + self.related_field().name_plural()
|
|
|
|
- if hasattr(self.field, "verbose_name_plural"):
|
|
|
|
- return unicode(self.field.verbose_name_plural)
|
|
|
|
- return self.name() + "s"
|
|
|
|
-
|
|
|
|
- def is_relation(self):
|
|
|
|
- return self.field.is_relation
|
|
|
|
-
|
|
|
|
- def is_multiple(self):
|
|
|
|
- if not self.is_relation():
|
|
|
|
- return False
|
|
|
|
- if self.field.one_to_many:
|
|
|
|
- return True
|
|
|
|
- if self.field.many_to_many:
|
|
|
|
- return True
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def related_model(self):
|
|
|
|
- if hasattr(self.field, "related_model"):
|
|
|
|
- return ModelData(self.field.related_model)
|
|
|
|
- if hasattr(self.field, "to"):
|
|
|
|
- return ModelData(self.field.to)
|
|
|
|
- return None
|
|
|
|
-
|
|
|
|
- def related_field(self):
|
|
|
|
- if hasattr(self.field, "field"):
|
|
|
|
- return FieldData(self.field.field, self.request)
|
|
|
|
- return None
|
|
|
|
-
|
|
|
|
- def is_auto(self):
|
|
|
|
- return self.field.auto_created
|
|
|
|
-
|
|
|
|
- def is_weak(self):
|
|
|
|
- if not self.is_relation():
|
|
|
|
- return False
|
|
|
|
- f = self.field
|
|
|
|
- if hasattr(f, "many_to_many") and f.many_to_many:
|
|
|
|
- return False
|
|
|
|
- if hasattr(f, "many_to_one") and self.field.many_to_one:
|
|
|
|
- return False
|
|
|
|
- if hasattr(self.field, "get_related_field"):
|
|
|
|
- o = self.field.get_related_field
|
|
|
|
- if self.field.one_to_one or self.field.one_to_many:
|
|
|
|
- if hasattr(o, "required"):
|
|
|
|
- return o.required
|
|
|
|
- return True
|
|
|
|
- if isinstance(f, models.ForeignKey):
|
|
|
|
- # noinspection PyUnresolvedReferences,PyProtectedMember
|
|
|
|
- return self.related_model()._meta.pk.name
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def filter_html(self):
|
|
|
|
- return filters.Filter.selection_type_html(self, self.request)
|
|
|
|
-
|
|
|
|
- def __str__(self):
|
|
|
|
- return self.bare_name()
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class ValueData:
|
|
|
|
- def __init__(self, value, field):
|
|
|
|
- self.value = value
|
|
|
|
- self.field = field
|
|
|
|
-
|
|
|
|
- def can_view(self):
|
|
|
|
- if self.field.is_relation():
|
|
|
|
- o = self.field.related_model()
|
|
|
|
- return registry.is_controlled(o)
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- def is_multiple(self):
|
|
|
|
- return self.field.is_multiple()
|
|
|
|
-
|
|
|
|
- def __str__(self):
|
|
|
|
- return str(self.field) + ': ' + str(self.value)
|
|
|
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
|
+from django.contrib.contenttypes.models import ContentType
|
|
|
|
+
|
|
|
|
+__author__ = 'marcos.medeiros'
|
|
|
|
+
|
|
|
|
+from rapid.registry import registry, Action
|
|
|
|
+from rapid import filters
|
|
|
|
+import rapidfields
|
|
|
|
+
|
|
|
|
+import itertools
|
|
|
|
+from django.db import models
|
|
|
|
+from rapid import permissions
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class InstanceData:
|
|
|
|
+ def __init__(self, instance, request=None, excludes=None, creator=None, fields=None):
|
|
|
|
+ excludes = [] if excludes is None else excludes
|
|
|
|
+ self.model = ModelData(type(instance), request, excludes, creator, fields)
|
|
|
|
+ self.instance = instance
|
|
|
|
+ self.request = request
|
|
|
|
+ self.excludes = excludes if excludes else []
|
|
|
|
+ self.creator = creator
|
|
|
|
+ self._fields = self.model.fields()
|
|
|
|
+
|
|
|
|
+ def values(self):
|
|
|
|
+ r = []
|
|
|
|
+ o = self.instance
|
|
|
|
+ for f in self.model.fields():
|
|
|
|
+ if f.is_relation:
|
|
|
|
+ r.append(self._value_of_field(o, f))
|
|
|
|
+ else:
|
|
|
|
+ r.append(self._value_of_field(o, f))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def _value_of_field(self, instance, field):
|
|
|
|
+ """
|
|
|
|
+ Returns the value of the given field.
|
|
|
|
+ ::return A tuple, with the actual value of the field, a boolean that is true iff
|
|
|
|
+ the value is iterable, and a sequence of URLs for the viewers of the instances
|
|
|
|
+ of the first element, or False if there are no viewers.
|
|
|
|
+ """
|
|
|
|
+ if hasattr(instance, field.accessor_name()):
|
|
|
|
+ v = getattr(instance, field.accessor_name())
|
|
|
|
+ else: # Many to many relations without value may disappear
|
|
|
|
+ return [], True
|
|
|
|
+ if hasattr(v, '__iter__'):
|
|
|
|
+ return (v, ()), True
|
|
|
|
+ if hasattr(v, 'all'):
|
|
|
|
+ return [(x, InstanceData(x, self.request, creator=(self, field))) for x in v.all()], True
|
|
|
|
+ if isinstance(v, models.Model):
|
|
|
|
+ return (v, InstanceData(v, self.request, creator=(self, field))), False
|
|
|
|
+ return (v, ()), False
|
|
|
|
+
|
|
|
|
+ def fields_and_values(self):
|
|
|
|
+ r = []
|
|
|
|
+ for field in self.model.fields():
|
|
|
|
+ value, is_multiple = self._value_of_field(self.instance, field)
|
|
|
|
+ r.append((field, value, is_multiple))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def is_controlled(self):
|
|
|
|
+ return self.model.is_controlled()
|
|
|
|
+
|
|
|
|
+ def can_read(self):
|
|
|
|
+ return self.has_permission(self.request, 'view')
|
|
|
|
+
|
|
|
|
+ def can_write(self):
|
|
|
|
+ return self.has_permission(self.request, 'edit')
|
|
|
|
+
|
|
|
|
+ def view_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model.model, "view", pk=self.instance.pk)
|
|
|
|
+
|
|
|
|
+ def edit_url(self):
|
|
|
|
+ url = registry.get_url_of_action(self.model.model, "edit", pk=self.instance.pk)
|
|
|
|
+ by = self.creator
|
|
|
|
+ if by:
|
|
|
|
+ dt, fd = by
|
|
|
|
+ if fd.one_to_one or fd.one_to_many:
|
|
|
|
+ # Do not change the parent of the viewer.
|
|
|
|
+ return url + "?default=" + fd.field.name + ":" + str(dt.object.pk)
|
|
|
|
+ if fd.many_to_one or fd.many_to_many:
|
|
|
|
+ return url
|
|
|
|
+ return url
|
|
|
|
+
|
|
|
|
+ def remove_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model.model, "delete", pk=self.instance.pk)
|
|
|
|
+
|
|
|
|
+ def create_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model.model, "add")
|
|
|
|
+
|
|
|
|
+ def list_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model.model, "list")
|
|
|
|
+
|
|
|
|
+ def select_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model.model, "select")
|
|
|
|
+
|
|
|
|
+ def actions(self):
|
|
|
|
+ r = []
|
|
|
|
+ acts = registry.model_entry(self.model.model)
|
|
|
|
+ if self.request and acts:
|
|
|
|
+ for a in acts.values():
|
|
|
|
+ if self.has_permission(self.request, a.action.name) and\
|
|
|
|
+ a.action.visibility > Action.Visibility.hidden:
|
|
|
|
+ r.append((a, a.get_url(self.instance)))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def model_actions(self):
|
|
|
|
+ r = []
|
|
|
|
+ for (a, u) in self.actions():
|
|
|
|
+ if not a.action.query_parameters:
|
|
|
|
+ r.append((a, u))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def instance_actions(self):
|
|
|
|
+ r = []
|
|
|
|
+ for (a, u) in self.actions():
|
|
|
|
+ if a.action.query_parameters:
|
|
|
|
+ r.append((a, u))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def list_actions(self):
|
|
|
|
+ r = []
|
|
|
|
+ for (a, u) in self.instance_actions():
|
|
|
|
+ if a.action.visibility == Action.Visibility.list:
|
|
|
|
+ r.append((a, u))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def has_permission(self, request, action_name):
|
|
|
|
+ m = registry.model_entry(self.model.model).get(action_name)
|
|
|
|
+ if m:
|
|
|
|
+ perm = m.permission.instances
|
|
|
|
+ return permissions.has_instance(self.model, perm(request), self.instance)
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def __unicode__(self):
|
|
|
|
+ return unicode(self.instance)
|
|
|
|
+
|
|
|
|
+ def __str__(self):
|
|
|
|
+ return str(self.model) + ': ' + str(self.instance.pk)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class ModelData:
|
|
|
|
+ def __init__(self, model, request=None, excludes=None, creator=None, fields=None):
|
|
|
|
+ excludes = [] if excludes is None else excludes
|
|
|
|
+ self.model = model
|
|
|
|
+ self.request = request
|
|
|
|
+ self.excludes = excludes if excludes else []
|
|
|
|
+ self.creator = creator
|
|
|
|
+ self._fields = [self.field_by_name(f) for f in fields] if fields else self.all_fields()
|
|
|
|
+
|
|
|
|
+ def model_name(self):
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ return unicode(self.model._meta.verbose_name)
|
|
|
|
+
|
|
|
|
+ def model_name_plural(self):
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ return unicode(self.model._meta.verbose_name_plural)
|
|
|
|
+
|
|
|
|
+ def default_manager(self):
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ return self.model._default_manager
|
|
|
|
+
|
|
|
|
+ def all_fields(self):
|
|
|
|
+ r = []
|
|
|
|
+ relations = []
|
|
|
|
+ for f in itertools.chain(self.local_fields(), self.related_fields()):
|
|
|
|
+ if f.is_relation():
|
|
|
|
+ relations.append(f)
|
|
|
|
+ else:
|
|
|
|
+ if f.name not in self.excludes:
|
|
|
|
+ r.append(f)
|
|
|
|
+ for f in relations:
|
|
|
|
+ if f.name not in self.excludes:
|
|
|
|
+ r.append(f)
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def fields(self):
|
|
|
|
+ return self._fields
|
|
|
|
+
|
|
|
|
+ def local_fields(self):
|
|
|
|
+ r = []
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ for f in self.model._meta.local_fields:
|
|
|
|
+ if f.name not in self.excludes:
|
|
|
|
+ r.append(FieldData(f, self.request))
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ for f in self.model._meta.local_many_to_many:
|
|
|
|
+ if f.name not in self.excludes:
|
|
|
|
+ r.append(FieldData(f, self.request))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def rapid_alternative_data(self):
|
|
|
|
+ """
|
|
|
|
+ :return: Tuples of the form (name, field) with the
|
|
|
|
+ AlternativeData fields of this model.
|
|
|
|
+
|
|
|
|
+ Those are not returned by fields()
|
|
|
|
+ """
|
|
|
|
+ for k, v in self.model.__dict__.iteritems():
|
|
|
|
+ if isinstance(v, rapidfields.AlternativeData):
|
|
|
|
+ yield (k, v)
|
|
|
|
+
|
|
|
|
+ def related_fields(self):
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ return [FieldData(f, self.request) for f in self.model._meta.get_all_related_objects()]
|
|
|
|
+
|
|
|
|
+ def is_controlled(self):
|
|
|
|
+ return registry.is_controlled(self.model)
|
|
|
|
+
|
|
|
|
+ def can_read(self):
|
|
|
|
+ if self.can_write():
|
|
|
|
+ return True
|
|
|
|
+ vw = registry.model_entry(self.model)['view'].permission(self.request)
|
|
|
|
+ if vw:
|
|
|
|
+ return vw.exists()
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def can_write(self):
|
|
|
|
+ ed = registry.model_entry(self.model)['edit'].permission(self.request)
|
|
|
|
+ if ed:
|
|
|
|
+ return ed.exists()
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def create_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model, "add")
|
|
|
|
+
|
|
|
|
+ def list_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model, "list")
|
|
|
|
+
|
|
|
|
+ def select_url(self):
|
|
|
|
+ return registry.get_url_of_action(self.model, "select")
|
|
|
|
+
|
|
|
|
+ def actions(self):
|
|
|
|
+ r = []
|
|
|
|
+ acts = registry.model_entry(self.model)
|
|
|
|
+ if self.request and acts:
|
|
|
|
+ for a in acts.values():
|
|
|
|
+ if self.has_permission(self.request, a.action.name) and\
|
|
|
|
+ not a.action.query_parameters and\
|
|
|
|
+ a.action.visibility > Action.Visibility.hidden:
|
|
|
|
+ r.append((a, a.get_url()))
|
|
|
|
+ return r
|
|
|
|
+
|
|
|
|
+ def has_permission(self, request, action_name):
|
|
|
|
+ m = registry.model_entry(self.model)
|
|
|
|
+ if m:
|
|
|
|
+ a = m.get(action_name)
|
|
|
|
+ if a:
|
|
|
|
+ return bool(a.permission.model(request))
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def field_by_name(self, field_name):
|
|
|
|
+ # noinspection PyProtectedMember
|
|
|
|
+ return FieldData(self.model._meta.get_field(field_name), self.request)
|
|
|
|
+
|
|
|
|
+ def content_type(self):
|
|
|
|
+ return ContentType.objects.get_for_model(self.model)
|
|
|
|
+
|
|
|
|
+ def __unicode__(self):
|
|
|
|
+ return unicode(self.model)
|
|
|
|
+
|
|
|
|
+ def __str__(self):
|
|
|
|
+ return 'Model: ' + str(self.model)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class FieldData:
|
|
|
|
+ def __init__(self, field, request=None):
|
|
|
|
+ self.field = field
|
|
|
|
+ self.request = request
|
|
|
|
+
|
|
|
|
+ @classmethod
|
|
|
|
+ def from_model(cls, model, field_name):
|
|
|
|
+ ff = ModelData(model).fields()
|
|
|
|
+ for f in ff:
|
|
|
|
+ if f.bare_name() == unicode(field_name):
|
|
|
|
+ return f
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ def bare_name(self):
|
|
|
|
+ return unicode(self.field.name)
|
|
|
|
+
|
|
|
|
+ def accessor_name(self):
|
|
|
|
+ if hasattr(self.field, 'get_accessor_name'):
|
|
|
|
+ return unicode(self.field.get_accessor_name())
|
|
|
|
+ return unicode(self.field.name)
|
|
|
|
+
|
|
|
|
+ def name(self):
|
|
|
|
+ if self.is_auto() and self.is_relation():
|
|
|
|
+ return self.related_model().model_name_plural() + u' - ' + self.related_field().name()
|
|
|
|
+ if hasattr(self.field, "verbose_name"):
|
|
|
|
+ return unicode(self.field.verbose_name)
|
|
|
|
+ return unicode(self.field.name)
|
|
|
|
+
|
|
|
|
+ def name_plural(self):
|
|
|
|
+ if self.is_auto() and self.is_relation():
|
|
|
|
+ return self.related_model().model_name_plural() + u' - ' + self.related_field().name_plural()
|
|
|
|
+ if hasattr(self.field, "verbose_name_plural"):
|
|
|
|
+ return unicode(self.field.verbose_name_plural)
|
|
|
|
+ return self.name() + "s"
|
|
|
|
+
|
|
|
|
+ def is_relation(self):
|
|
|
|
+ return self.field.is_relation
|
|
|
|
+
|
|
|
|
+ def is_multiple(self):
|
|
|
|
+ if not self.is_relation():
|
|
|
|
+ return False
|
|
|
|
+ if self.field.one_to_many:
|
|
|
|
+ return True
|
|
|
|
+ if self.field.many_to_many:
|
|
|
|
+ return True
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def related_model(self):
|
|
|
|
+ if hasattr(self.field, "related_model"):
|
|
|
|
+ return ModelData(self.field.related_model)
|
|
|
|
+ if hasattr(self.field, "to"):
|
|
|
|
+ return ModelData(self.field.to)
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ def related_field(self):
|
|
|
|
+ if hasattr(self.field, "field"):
|
|
|
|
+ return FieldData(self.field.field, self.request)
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ def is_auto(self):
|
|
|
|
+ return self.field.auto_created
|
|
|
|
+
|
|
|
|
+ def is_weak(self):
|
|
|
|
+ if not self.is_relation():
|
|
|
|
+ return False
|
|
|
|
+ f = self.field
|
|
|
|
+ if hasattr(f, "many_to_many") and f.many_to_many:
|
|
|
|
+ return False
|
|
|
|
+ if hasattr(f, "many_to_one") and self.field.many_to_one:
|
|
|
|
+ return False
|
|
|
|
+ if hasattr(self.field, "get_related_field"):
|
|
|
|
+ o = self.field.get_related_field
|
|
|
|
+ if self.field.one_to_one or self.field.one_to_many:
|
|
|
|
+ if hasattr(o, "required"):
|
|
|
|
+ return o.required
|
|
|
|
+ return True
|
|
|
|
+ if isinstance(f, models.ForeignKey):
|
|
|
|
+ # noinspection PyUnresolvedReferences,PyProtectedMember
|
|
|
|
+ return self.related_model()._meta.pk.name
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def filter_html(self):
|
|
|
|
+ return filters.Filter.selection_type_html(self, self.request)
|
|
|
|
+
|
|
|
|
+ def __str__(self):
|
|
|
|
+ return self.bare_name()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class ValueData:
|
|
|
|
+ def __init__(self, value, field):
|
|
|
|
+ self.value = value
|
|
|
|
+ self.field = field
|
|
|
|
+
|
|
|
|
+ def can_view(self):
|
|
|
|
+ if self.field.is_relation():
|
|
|
|
+ o = self.field.related_model()
|
|
|
|
+ return registry.is_controlled(o)
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ def is_multiple(self):
|
|
|
|
+ return self.field.is_multiple()
|
|
|
|
+
|
|
|
|
+ def __str__(self):
|
|
|
|
+ return str(self.field) + ': ' + str(self.value)
|