I have solve it!

The point is to use a variable not a constant for recursion's file
name. Why recursion? I've translated my model into rendering context.
And if a field is a relationship with fields, the rendering is the
same.

Here is the template:

<div class="contextName" id="{{contextPrefix}}
{{contextElement.name}}">
    <div class="contextLabel">
        {{contextElement.label}}:
    </div>
    <div class="contextValue">
        {% if contextElement.href %}
            <div class="contextUrl">
                <a class="contextUrl" href="{{contextElement.href}}">
{{contextElement.value}}</a>
            </div>
        {% else %}
            {{contextElement.value}}
        {% endif %}
    </div>
    {% if contextElement.fields %}
        {% comment %}
            Use contextElement.field.aFieldName for individual field
rendering!
        {% endcomment %}
        {% if not contextRecursionForbidden %}
            <div class="contextFields">
                {% for field in contextElement.fields %}
                    {% with field as contextElement %}
                        {% comment %} Uncomment this line for stop
recursion!
                            {% with field as contextRecursionForbidden
%}
                                {% endcomment %}
                                    {% with field.name as
contextPrefix %}
                                        {% with
"context_element_template.html" as context_element_template %}
                                            {% include
context_element_template %}
                                        {% endwith %}
                                    {% endwith %}
                                {% comment %} Uncomment this line for
stop recursion!
                            {% endwith %}
                        {% endcomment %}
                    {% endwith %}
                {% endfor %}
            </div>
        {% endif %}
    {% endif %}
    {% if contextElement.queryset %}
        <div class="contextQueryset">
            <ul>
                {% for object in contextElement.queryset %}
                    <li>
                        {% comment %}
                            Obviously queried contexts have only value
and url.
                            Use queriedContext.fields for rendering
object's fields or
                            queriedContext.field.aFieldName for
rendering object's individual field
                        {% endcomment %}
                        {% if object.href %}
                            <div class="contextUrl">
                                <a class="contextUrl"
href="{{object.href}}">{{object.value}}</a>
                            </div>
                        {% else %}
                            {{object.value}}
                        {% endif %}
                    </li>
                {% endfor %}
            </ul>
        </div>
    {% endif %}
    <div class="clear">
        <!-- -->
    </div>
</div>

And here is the rendering code:

class ContextElement:

    def __unicode__(self):
        try:
            return self.value
        except AttributeError:
            pass
        return ""

    def __iter__(self):
        try:
            return self.fields
        except AttributeError:
            pass
        try:
            return self.queryset
        except AttributeError:
            pass
        return []

    def __init__(self, *args, **kwargs):

        args_help = "ContextElement(\n\
            [model|(instance [, field_meta])]\n\
            [, value = value]\n\
            [, label = label]\n\
            [, name = name]\n\
            [, href = href]\n\
            [, fields = fields]\n\
            [, queryset = queryset]\n\
        )"

        for k, v in kwargs.items():
            if k in ('value', 'label', 'name', 'href', 'fields',
'queryset'):
                setattr(self, k, v)
            else:
                raise Exception(args_help)

        if len(args) == 0:
            return

        try:
            ismodel = issubclass(args[0], models.Model)
        except TypeError:
            ismodel = False
        if ismodel:
            if len(args) > 1:
                raise Exception(args_help)
            model = args[0]
            opts = model._meta
            name = opts.object_name
            label = opts.verbose_name_plural
            queryset = model.objects.all()._clone(klass =
ContextQuery)

        else:
            if not isinstance(args[0], models.Model):
                raise Exception(args_help)
            instance = args[0]

            if len(args) > 1:
                if len(args) > 2:
                    try:
                        isfield = issubclass(args[0], Field)
                    except TypeError:
                        isfield = False
                    if not isfield:
                        raise Exception(args_help)
                field_meta = args[1]
                field_instance = getattr(instance, field_meta.name)
                name = field_meta.name
                label = field_meta.verbose_name

                if field_meta.rel:
                    value = field_instance

                    if isinstance(field_meta.rel,
models.ManyToOneRel):
                        if hasattr(field_instance,
'get_absolute_url'):
                            href = getattr(field_instance,
'get_absolute_url')
                        fields = ContextElement(field_instance).fields

                    elif isinstance(field_meta.rel,
models.ManyToManyRel):
                        queryset = field_instance.all()._clone(klass =
ContextQuery)

                elif field_meta.choices:
                    value = getattr(field_instance, 'get_' +
field_meta.name + '_display')

                elif isinstance(field_meta, models.DateField) or
isinstance(field_meta, models.TimeField):
                    date_format, datetime_format, time_format =
get_date_formats()
                    if isinstance(field_meta, models.DateTimeField):
                        format = datetime_format
                    elif isinstance(field_meta, models.TimeField):
                        format = time_format
                    else:
                        format = date_format
                    value = dateformat.format(field_instance,
format).capitalize()

                elif isinstance(field_meta, models.BooleanField) or
isinstance(field_meta, models.NullBooleanField):
                    value = { True: _("Yes"), False: _("No"), None: _
("Unknown") } [field_instance]

                else:
                    value = field_instance

            else:
                opts = instance._meta
                name = opts.object_name
                label = opts.verbose_name
                value = instance
                if hasattr(instance, 'get_absolute_url'):
                    href = getattr(instance, 'get_absolute_url')
                fields = [ContextElement(instance, field_meta) for
field_meta in opts.fields]
#                 fields += [
#                     ContextElement(instance, related.field) for
related in (
#                         opts.get_all_related_objects() +
#                         opts.get_all_related_many_to_many_objects()
#                     )
#                 ]

        try:
            self.value = value
        except NameError:
            pass
        try:
            self.name = name
        except NameError:
            pass
        try:
            self.label = label.capitalize()
        except NameError:
            pass
        try:
            self.href = href
        except NameError:
            pass
        try:
            self.queryset = queryset
        except NameError:
            pass
        try:
            self.fields = fields
        except NameError:
            pass
        try:
            self.field = ContextDictionary(self.fields)
        except (NameError, AttributeError):
            pass

On 31. Aug, 15:50 h., Karen Tracey <kmtra...@gmail.com> wrote:
> On Mon, Aug 31, 2009 at 9:03 AM, gentlestone <tibor.b...@hotmail.com> wrote:
>
> > is recursion allowed in templates?
>
> > for example can the "xy_template.html" file contain {% include
> > "xy_template.html" %}?
>
> It's "allowed" in the sense that it's not caught as an error.  But it will
> lead to infinite recursion...
>
>
>
> > because I tried but the system crushed:
>
> ...which is what you are seeing here.  For some reason it often seems that
> instead of reporting maximum recursion depth exceeded, Python on Macs crash.
>
> So no, it's not something you actually want to do.  What is the real problem
> you are trying to solve by including a template inside itself?
>
> Karen
>
>
>
> > Process:         Python [97385]
> > Path:            /System/Library/Frameworks/Python.framework/Versions/
> > 2.5/Resources/Python.app/Contents/MacOS/Python
> > Identifier:      Python
> > Version:         ??? (???)
> > Code Type:       X86 (Native)
> > Parent Process:  Python [97384]
>
> > Interval Since Last Report:          3912 sec
> > Crashes Since Last Report:           12
> > Per-App Interval Since Last Report:  0 sec
> > Per-App Crashes Since Last Report:   12
>
> > Date/Time:       2009-08-31 15:02:00.210 +0200
> > OS Version:      Mac OS X 10.5.7 (9J61)
> > Report Version:  6
> > Anonymous UUID:  BD3D5563-F1EA-4DC8-9293-5BCBADDFA1DE
>
> > Exception Type:  EXC_BAD_ACCESS (SIGBUS)
> > Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000b0000fec
> > Crashed Thread:  1
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to