calebsmith / django-template-debug

A small collection of template tags for debugging and introspecting templates
BSD 3-Clause "New" or "Revised" License
74 stars 11 forks source link

Question about output #35

Open Chris-May opened 8 years ago

Chris-May commented 8 years ago

I've been using django-template-debug with the Wagtail CMS, and I'm getting unexpected output from this projects tags. For example:

{% variables %}
{% attributes self %}
{% details self %}

Produces:

['False', 'None', 'True', 'hero_photo', 'self', 'value']

<filter object at 0x111da2e48>

{'get': 'routine', 'update': 'routine', 'pop': 'routine', 'copy': 'routine', 'keys': 'routine', 'popitem': 'routine', 'block': <home.models.RichTextWithForm object at 0x110d729e8>, 'setdefault': 'routine', 'fromkeys': 'routine', 'move_to_end': 'routine', 'bound_blocks': OrderedDict([('body', <wagtail.wagtailcore.blocks.base.BoundBlock object at 0x111da2940>), ('image', <wagtail.wagtailcore.blocks.base.BoundBlock object at 0x111da2ac8>), ('reverse_text', <wagtail.wagtailcore.blocks.base.BoundBlock object at 0x111da22b0>), ('resource_given', <wagtail.wagtailcore.blocks.base.BoundBlock object at 0x111da2e10>), ('save_contact_to', <wagtail.wagtailcore.blocks.base.BoundBlock object at 0x111da2320>)]), 'clear': 'routine', 'items': 'routine', 'values': 'routine'}

I routinely get results like this, so I never use the attributes tag, and I have to dig around all the routine values to find meaningful values.

I'm wondering if this has to do with the Wagtail CMS, or if it has to do with Django changing over the last two years.

calebsmith commented 8 years ago

This is pretty interesting. Thanks for the report!

In all honesty, this project needs a bit of Django upgrade love. I haven't been doing much Django for about a year and should probably look for another maintainer for this project long term.

I have a hunch that the attributes is returning this filter object because something in Django that used to be eager is now lazy, or that this change is introduced from using Python 3 rather than 2. If I recall correctly, this project works for Python 2 and 3, but I wouldn't be surprised if this wasn't the underlying issue. I think what attributes does is basically like details but only taking the keys, which is now lazy in Python 3. We could probably just wrap this in list() to make it work.

The variables tag and details tags have values I would expect, though I don't remember seeing bound_blocks before in particular. This seems to have objects that wagtail defines so I suspect that's where this bit is coming from.

There could be something that makes details output more useful. For instance, methods and functions appear as "routine" rather than the built-in representation. I don't see how you'd do something like this for wagtail data though, beyond adding in an extension mechanism where a function from the settings gets called with the output to act as a transformation to what you want. For something like wagtail, this might be a really useful feature.

In short, I think the main crux of the issue here, and the fix, would be to see what attributes is doing and possibly forcing evaluation there with list().

calebsmith commented 8 years ago

I wanted to give a quick comment to amend part of the above. I was right about the laziness/eagerness issue but wrong about the source of the problem. The line of code in question is here: https://github.com/calebsmith/django-template-debug/blob/master/template_debug/utils.py#L76

This uses filter(). I suspect this never worked correctly for Python 3. We just need to wrap this in list() or change it to its eager equivalent

Chris-May commented 8 years ago

One option for replacing return 'routine' I am testing out is return repr(value) instead. This seems to at least give some context to what the attribute is. It seems to work so far!

I'll try testing it and the other change I made to see if anything comes up. Since it looks like the automated testing connected to this repo is out of date or something (sorry for uncovering more stuff to deal with).

calebsmith commented 8 years ago

Hi Chris,

Sure thing, no worries. I do need to fix the build setup before I can really merge stuff in. Your PR for this issue LGTM and I appreciate the contribution.

For the "routine" piece, there is kind of a personal preference here that maybe we should make configurable? Essentially, the idea of just displaying "routine" is so that you'll know as a template author that something is a method or function and not just plain data. The repr() is often a bit verbose and I never found it very helpful. I've often thought that wiring in a bit of introspection would be the most useful here, like possibly showing file name and line number information. If the repr() seems generally more helpful to you (or others), I'm happy to be convinced though.

Chris-May commented 8 years ago

I like the idea of having some introspection, for sure! I'm not yet familiar enough with the django ecosystem to be able to contribute a ton there.

In the interim, I do like that the repr option let's me know what type of object it is, so I can (hopefully) better understand what's going on. Thus far, I've tried replacing the variable in the {% details foo %} tag just to see what values are hidden under the 'routine' output. Now I can at least know where I can look in the source code to see what's happening.

Unrelated to the above, what do you think of outputting the results of details into a <pre> tag? I think it might be useful to have a indented format to better see individual items over a run-on sentence of attributes and values. But I might be more of a special case, learning as I go.

calebsmith commented 8 years ago

Hi Chris,

I think something like that could work. We might also need to use a pretty print function or something to get what you want.

As far as the introspection piece, I took a stab at it once but did a lot of poking at internals and it didn't port to Python 3 well. I eventually abandoned it. However, I believe there is a standard Python module for introspection that could help. (This could be a pie in the sky future feature)

FlipperPA commented 6 years ago

Howdy folks. I'm a Wagtail user as well, and wondering how this ended up. I saw the PR from @Chris-May and wondering how we can get this published.

calebsmith commented 6 years ago

Sorry it took me so long to get to this. I haven't used this project in quite a while and need to find a new maintainer. Chris' fix is obviously correct so I merged it in even though the build is failing. The builds are failing because something with the test setup stopped working (completely unrelated to these changes).

I'm at a bit of an impasse. After merging in the PR and bumping the version, I can't publish to pypi because I forgot my password a very long time ago. For now, you should be able to point your dependency at the github tag for v0.3.6

FlipperPA commented 6 years ago

Howdy @calebsmith, thanks for hopping on this, and all your efforts so far! If you'd like, I can take over maintaining it. I'm a member of the Django Software Foundation and a DjangoCon US organizer. We may be able to find a permanent home for it at JazzBand - or, even better, I'll recommend including it in Django contrib, as its a very useful debugging tool for beginners. I've done a fair amount of work trying to make Django more friendly to newcomers, and this would fall in line with those efforts. I've got quite a few packages published on PyPI as well.