Commits

Osiloke Emoekpere committed 2695b62

Added {% can_edit %} tags

  • Participants
  • Parent commits 5a52c9d

Comments (0)

Files changed (2)

frontend/templates/frontend/editable_form.html

 {% load i18n %}
 
 {# Edit form #}
-<form style="display:none;" class="editable-form" method="post" 
-    action="{% url edit %}" id="{{ form.uuid }}" 
+<form style="display:none;" class="popup-form editable-form" method="post"
+    action="{{ action }}" id="{{ form.uuid }}"
     {% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
     {% csrf_token %}
     {% for field in form %}

frontend/templatetags/frontend_tags.py

 from django.template.loader import get_template
 from django import template
 from django.core.urlresolvers import reverse
+from mezzanine.core.forms import get_edit_form
+from mezzanine.utils.views import is_editable
 
 from frontend.utilities import  checkObjectFields, can
 from frontend.forms import get_model_form
- 
+
 from classytags.core import Tag, Options
 from classytags.arguments import Argument, MultiKeywordArgument, MultiValueArgument, KeywordArgument
 from classytags.helpers import InclusionTag
 logger = logging.getLogger(__name__)
 
 
+class can_edit(Tag):
+    """
+    {% can_edit [model_name] %}
+    """
+    name = 'can_edit'
+    options = Options(
+        Argument('model', resolve=False,required=True),
+        MultiValueArgument('fields', resolve=False, required=False),
+        'using',
+        MultiKeywordArgument('values', resolve=True, required=False),
+        'params',
+        KeywordArgument('action', required=False),
+        KeywordArgument('template', required=False),
+        blocks=[
+            ('endcan_edit', 'nodelist')
+        ]
+    )
+
+    def render_tag(self, context, **kwargs):
+        def value_ids(values):
+            "returns the ids of the values needed to populate the model form"
+            parsed_values = {}
+            for key in values:
+                value = values[key]
+                if isinstance(value, Model):
+                    parsed_values[key] = value.id
+                else:
+                    parsed_values[key] = value
+            return parsed_values
+
+        def parse_field(field):
+            field = field.split(".")
+            obj = context[field.pop(0)]
+            attr = field.pop()
+            while field:
+                obj = getattr(obj, field.pop(0))
+            return obj, attr
+
+        def parse_model(model):
+            field = model.split(".")
+            obj = context[field.pop(0)]
+
+            parent_model = None
+            parent_model_field_name_for_object = None
+            while field:
+                if isinstance(obj, dict) or isinstance(obj,list):
+#                if hasattr(obj, "__iter__") and len(obj) > 0:
+                    """
+                    Fix to ignore parent object if it is a list or tuple
+                    A list cannot be the parent of a django model or field so we reset the obj and try with next field
+                    """
+                    obj = obj[field.pop(0)]
+                    obj = obj.__class__
+                    parent_model = None
+                else:
+                    parent_model = obj
+                    next_field=field.pop(0)
+                    obj = getattr(obj, next_field)
+                    if hasattr(obj, "model"):
+                        obj = obj.model
+                    try:
+                        parent_model_field_name_for_object = parent_model._meta.get_field_by_name(next_field)[0]
+                    except:
+                        pass
+            return obj, parent_model, parent_model_field_name_for_object
+
+        model = kwargs.get("model", None)
+        nodelist = kwargs.get('nodelist', None)
+        parsed = nodelist.render(context)
+
+        fields = kwargs.get('fields', None)
+        values = kwargs.get('values', None)
+
+        parent_model_name = None
+        parent_model_id = None
+        parent_model_related_name = None
+
+        model, parent_model, parent_model_field_name_for_object = parse_model(model)
+
+        if parent_model:
+            parent_model_name = parent_model._meta.module_name
+            parent_model_id = parent_model.id
+            try:
+                parent_model_related_name = parent_model_field_name_for_object.related_query_name()
+            except Exception:
+                pass
+
+        #If model is a related manager, get the model object
+        if hasattr(model, "model"):
+            model = model.model
+        #if model is a collection, get first object
+        elif hasattr(model, "__iter__") and len(model) > 0:
+            model = model[0]
+        if fields and model:
+            field_names = ",".join([f for f in fields])
+            if can('edit', model, context["user"]):
+#                'Assign page to new content model'
+#                if not isinstance(model, Model):
+#                    content_model = model()
+#                else:
+#                    content_model = model.__class__()
+                context["form"] = get_model_form(model, field_names, \
+                                 values=value_ids(values), \
+                                 parent_model=parent_model_name, \
+                                 parent_model_related_name=parent_model_related_name, \
+                                 parent_id=parent_model_id )
+
+                context["original"] = parsed
+                context["add_text"] = model._meta.verbose_name.title()
+                #you can provide a different action for the form to submit to
+
+                try:
+                    action = kwargs.get("action", None)
+                    context["action"] = action["action"]
+                except KeyError:
+                    context["action"] = reverse("frontend_edit")
+                t = get_template("frontend/editable_form.html")
+                return t.render(Context(context))
+        return parsed
+
+register.tag(can_edit)
+
+
 class can_add(Tag):
     """
     {% can_add [model_name] fields using field=value %}
             try:
                 parent_model_related_name = parent_model_field_name_for_object.related_query_name()
             except Exception, e:
-                raise e
+                pass
+#                raise e
 
         #If model is a related manager, get the model object
         if hasattr(model, "model"):