Commits

Dmitri Lebedev  committed ff9866f

initial

  • Participants

Comments (0)

Files changed (8)

File example/django_inline/__init__.py

+def templates_list(name, obj):
+	return [
+		'%s/%s/%s' % (obj._meta.app_label, obj.__class__.__name__, name),
+		'%s/%s' % (obj._meta.app_label, name),
+		name,
+	]

File example/django_inline/templates/inline-editable.html

+<span class="jeditable" id="{{ label }}.{{ class }}.{{ id }}.{{ field }}">{{ inner }}</span>

File example/django_inline/templates/inline-form.html

+{% load i18n %}
+<form action="{% url django_inline_update %}" method="POST" id="django_inline">
+	{% csrf_token %}
+	{{ form.id }}
+	{{ form.value }}
+	&nbsp;
+	<button type="submit">{% trans 'Save' %}</button>
+</form>'

File example/django_inline/templatetags/__init__.py

Empty file added.

File example/django_inline/templatetags/inline.py

+# coding=utf-8
+from django.template import Library, Node, TemplateSyntaxError, render_to_string
+from django_inline import templates_list
+
+register = Library()
+
+@register.tag
+def editable(parser, token):
+    """
+    Puts a jeditable HTML element (span.jeditable) around the contents of the tag.
+    Usage:
+       {% editable object field_name %}
+    """
+    bits = token.contents.split()    
+    
+    nodelist = parser.parse(('endeditable',))
+    parser.delete_first_token()
+    
+    if len(bits) != 3:
+        raise TemplateSyntaxError("%s tag requires exactly two arguments: object and the field to edit" % bits[0])
+    
+    return EditableNode(nodelist, parser.compile_filter(bits[1]), bits[2])
+
+
+class EditableNode(Node):
+    def __init__(self, nodelist, obj, field):
+        self.nodelist = nodelist
+        self.obj = obj
+        self.field = field
+
+    def render(self, context):
+        inner_content = self.nodelist.render(context)
+        obj = self.obj.resolve(context)
+        class_name = obj.__class__.__name__
+        app_label = obj._meta.app_label
+        
+        if not context['user'].has_perm('%s.can_edit' % class_name):
+            return inner_content
+        
+        return render_to_string(templates_list('inline-editable.html', obj), {
+            'class': class_name,
+            'label': app_label,
+            'id': obj.id,
+            'field': self.field,
+            'inner': inner_content,
+        })
+
+
+

File example/django_inline/urls.py

+from django.conf.urls.defaults import patterns, url
+
+urlpatterns = patterns('django_inline.views',
+    url(r'^widget/', 'widget', name='django_inline_widget'),
+    url(r'^update/', 'update', name='django_inline_update'),
+)

File example/django_inline/views.py

+from django.shortcuts import render_to_response, get_object_or_404
+from django.http import HttpResponse, Http404
+from django.db.models import get_model
+from django.contrib import admin
+from django import forms
+from django_inline import templates_list
+
+
+def _raise_error(label):
+    raise Http404('Bad object id: "%s"' % label)
+
+
+def get_params(func):
+    def decorated(request):
+        id = request.GET.get('id') or request.POST.get('id')
+        try:
+            class_name, app_label, pk, field_name = id.split('.')
+        except ValueError:
+            _raise_error(id)
+        
+        model = get_model(app_label, class_name)
+        if model is None:
+            _raise_error(id)
+        
+        obj = get_object_or_404(model, pk=int(pk))
+        return func(request, obj, field_name, id)
+    
+    return decorated
+
+
+@get_params
+def widget(request, obj, field_name, id):
+    class Form(forms.Form):
+        id = forms.CharField(widget=forms.HiddenInput())
+        value = admin.site._registry[obj.__class__].get_form(obj.pk).base_fields[field_name]
+    
+    return render_to_response(templates_list('inline-form.html', obj), {
+        'form': Form(initial={'id': id, 'data': getattr(obj, field_name)}),
+    })
+
+
+@get_params
+def update(request, obj, field_name, id):
+    if request.user.has_perm('%s.can_edit' % obj.__class__.__name__):
+        setattr(obj, field_name, request.POST['data'])
+        obj.save()
+    
+    return HttpResponse(getattr(obj, field_name))
+from setuptools import setup, find_packages
+
+setup(
+    name='django-inline',
+    version='0.1',
+    license='GNU Lesser GPL',
+    author='Dmitri Lebedev',
+    author_email='detail@ngs.ru',
+    description="""
+    """,
+    include_package_data=True,
+    zip_safe=False,
+    package_dir={'': 'example'},
+    packages=find_packages('example', exclude=('*.pyc', '*~'))
+)