Infinite recursion while extending the admin's

2019-03-25 04:10发布

I have the following template in template/admin/change_form.html:

{% extends "admin/change_form.html" %}
{% block extrahead %}
  {% include "dojango/base.html" %}
  {% block dojango_content %}
  {% endblock %}
{% endblock %}

However for some reason it throws a

TemplatesyntaxError: TemplateSyntaxError at /admin/cms/post/add/
Caught RuntimeError while rendering: maximum recursion depth exceeded while calling a Python object

6条回答
Anthone
2楼-- · 2019-03-25 04:35

With Django core it's impossible. But it is not impossible.

Copy and paste "the original template and change things you don't like" it's very ugly.

Don't make in the templates, whatever you don't make in python

This solution is to any template:

http://pypi.python.org/pypi/django-smart-extends

查看更多
Lonely孤独者°
3楼-- · 2019-03-25 04:49

I know it's late, but...

If extending - which is a far better option than duplicating - the key is to have it named anything except /admin/change_form.html.

(Although the OP referred to template/admin/change_form.html, this is simply because a path in his TEMPLATE_DIRS tuple ends in '/template' - mine generally end in '/templates' - but, these directories can be named anything and located anywhere.)

It will be used automatically on a per-app basis if named /admin/<MyAppName>/change_form.html

It will be used automatically on a per-model basis if named /admin/<MyAppName>/<MyModelName>/change_form.html

It can be named anything if specified explicitly in the ModelAdmin

class MyModelAdmin(admin.ModelAdmin):
    change_form_template = 'subdir/my_change_form.html'

Finally, if insistent on naming it /admin/change_form.html, you can - provided that the extends tag contains the full path to your django installation instead of a relative one.

查看更多
太酷不给撩
4楼-- · 2019-03-25 04:53

I had the same problem. Solved by placing the overridden template under myapp/templates/admin/myapp instead of myapp/templates/admin.

查看更多
贼婆χ
5楼-- · 2019-03-25 04:54

The best way to do this that I have found is to use '..' to go up a couple of directories, then go back down into directories that should only be found in the Django code base.

As the Django templates are in something like "django/contrib/admin/templates/admin", I found that this worked me:

{% extends "../../admin/templates/admin/change_form.html" %}

If that still causes a clash with some other structure you have, you could go further:

{% extends "../../../contrib/admin/templates/admin/change_form.html" %}

or even:

{% extends "../../../../django/contrib/admin/templates/admin/change_form.html" %}

Although it is a little hacky, at least by doing the above you don't have to use some other technique that involves copying the django source or setting up a symlink.

查看更多
我欲成王,谁敢阻挡
6楼-- · 2019-03-25 04:57

You are in admin/change_form.html and you extend admin/change_form.html. You cannot extend the same template which you are in.

You probably expected that if you override template from admin application, you can extend the one you override. But this is not how it works. When you override a template you cannot access it.

Solution to your problem is to copy original template and change things you don't like.

查看更多
Explosion°爆炸
7楼-- · 2019-03-25 05:00

Also, you can point your AdminOptions class to another template using the change_form_template property.

Something like:

class MyOptions(AdminOptions):
    change_form_template = 'myapp/my_change_form.html'

And myapp/my_change_form.html:

{% extends "admin/change_form.html" %}
查看更多
登录 后发表回答