添加到django管理页面的链接

时间:2012-03-26 14:03:07

标签: python django django-admin

我的客户端有一个用django构建的应用程序。在每一页上 他们的应用程序是他们的管理网站的链接。他们告诉我管理员网站 完全由django生成,他们从未定制过 之前。在管理页面的第一行,它说:

Django administration          Welcome, admin. Change password / Log out

他们希望我在“Django”的左侧添加一个指向该行的链接 管理“将把他们带回他们所在的页面 他们点击链接将他们带到管理站点。

所以我在这里有2个问题:

  1. 如何覆盖该行以添加链接?看来那页 由contrib / admin / templates / admin / base.html生成,我试过了 按照指示来覆盖它 https://docs.djangoproject.com/en/1.2/ref/contrib/admin/#overriding-a ..., 但无论我做什么似乎都没有效果。

  2. 如何获取他们来自的应用页面的链接?它的 不仅仅是回到一页,因为他们可以导航所有 在单击“返回应用程序”之前在管理站点的位置 链接。

2 个答案:

答案 0 :(得分:13)

有很多方法可以将最后访问过的非管理员网址存储在request.session中。例如,中间件:

import re

class LastSiteUrl(object):
    def is_admin_url(self, url):
        return re.search('^(http:\/\/.*){0,1}\/admin\/', url) is not None

    def process_request(self, request):
        if self.is_admin_url(request.path) and \
            not self.is_admin_url(request.META.get('HTTP_REFERER','')):
            request.session['last_site_url'] = request.META.get('HTTP_REFERER','')

然后覆盖模板:

  1. 将最后一个非管理员网址存储在request.session 中,例如将上述课程放在yourproject/middleware.py中,添加到settings.MIDDLEWARE_CLASSESmiddleware.LastSiteUrl

  2. 准备管理基础网站模板以覆盖,将django/contrib/admin/templates/admin/base_site.html复制到yourproject/templates/admin/base_site.html

  3. 指向request.session.last_site_url 的链接,例如在yourproject/templates/admin/base_site.html中,在此块的H1标记之前找到{% block branding %},添加到{{ request.session.last_site_url }}的HTML链接。

  4. 看起来应该是这样的:

    {% block branding %}
        {% if request.session.last_site_url %}
            <a href="{{ request.session.last_site_url }}">back to site</a>
        {% endif %}
        <h1 id="site-name">{% trans 'Django administration' %}</h1>
    {% endblock %}
    

答案 1 :(得分:1)

简单方法:

如果模型具有get_absolute_url函数,则管理员“更改”页面包含页面右上角的“网站视图”按钮。因此,请确保您的模型包含get_absolute_url:

    def get_absolute_url(self):
        return '/myapp/%s' %self.slug #this should reflect your url-structure.

“在网站上查看”按钮不在“添加”页面上,因为需要先创建对象才能访问它。告诉客户他/她创建新对象时不要点击“保存”但“保存并继续编辑”而不是点击“网站上的视图”。

现在,通过覆盖base_site.html,可以轻松跳转到当前模型条目的网站表示。在这里,我们检查当前模型是否包含absolute_url。如果您不在change_page上,则不会有absolute_url。在这种情况下,链接会将您带到主页。

模板/管理/ base_site.html

{% extends "admin/base.html" %}
{% load i18n %}

{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}

{% block branding %}
<h1 id="site-name">{% if has_absolute_url %}<a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">{% else %}<a href="http://{{ site.domain }}">{% endif %}{{ site.domain }}</a>    

 Sitebeheer{#{% trans 'Django administration' %}#}</h1>
{% endblock %}

{% block nav-global %}{% endblock %}

完成!

以下解决方案也会以不同的方式回答您的问题。这将在管理员“添加”和“更改”页面上的“保存并继续”和“保存”按钮旁边添加“在网站上保存并查看”按钮:

  1. 确保您的模型包含get_absolute_url函数。
  2. 覆盖管理员响应以重定向到此absolute_url。
  3. 覆盖change_form.html以添加“在网站上保存并查看”按钮。
  4. 编辑myproject / myapp / models.py

    class MyModel(models.Model):
        title = models.CharField("titel", max_length=200)
        slug = models.SlugField(unique=True)
    
        def __unicode__(self):
            return self.title
    
        def get_absolute_url(self):
            return '/myapp/%s' %self.slug
    

    编辑myproject / myapp / admin.py

    from models import MyModel
    
    class MyModelAdmin(admin.ModelAdmin):
        ...
    
        def response_change(self, request, obj):
            """
            Determines the HttpResponse for the change_view stage.
            """
            if request.POST.has_key("_viewsite"):
                msg = (_('The %(name)s "%(obj)s" was changed successfully.') %
                       {'name': force_unicode(obj._meta.verbose_name),
                        'obj': force_unicode(obj)})
                return HttpResponseRedirect(obj.get_absolute_url())
            return super(MyModel, self).response_change(request, obj)
    
    admin.site.register(MyModel, MyModelAdmin)
    

    创建一个新文件myproject / templates / admin / myapp / change_form.html:

    {% extends "admin/change_form.html" %}
    {% load i18n %}
    {% block content %}
    {{ block.super }}
    <script type="text/javascript">//<![CDATA[
        (function($){
            $('<input type="submit" value="Save and view on site" name="_viewsite" />')
            .prependTo('div.submit-row');
        })(django.jQuery);
    //]]></script>
    {% endblock %}
    

    模板将覆盖myapp中每个模型的change_form。在您的情况下这可能是不合需要的,因为并非所有模型都在网站中有代表(没有并且不需要get_absolute_url)。我认为您也可以将模板放在myproject / templates / admin / myapp / MyModel /change_form.html中,仅覆盖MyModel的模板,并将其他模型保留在myapp中,使用默认模板。我从未在单个模型中使用change_form模板。如果有效,你会告诉我吗?

    非常感谢你:http://djangosnippets.org/snippets/2005/

    这回答了你的问题吗?我希望它有所帮助。