django admin自定义

自定义 Django admin

核心观点

  1. UI是很重要的。
  2. 考虑初学者,DashBoard。
  3. 导航。
  4. 用户工作流。
  5. Django admin 缺少 WYSIWYG,文件管理,undo。

建议

  1. 了解用户的行业和工作流。
  2. 了解客户团队中的各个不同角色。
  3. 使用客户习语。
  4. 了解之前使用的工具,及其优缺点。

实现

ModelAdmin Media

class ArticleAdmin(admin.ModelAdmin):
    class Media:
        css = {
            "all": ("my_styles.css",)
        }
        js = ("my_code.js",)

优点:对于“一次性”项目简单。
缺点:只对Change Form有效。

Custom Templates

关键模板

  admin/base.html
  admin/index.html
  admin/change_form.html
  admin/change_list.html

  app_index.html
  delete_confirmation.html

  object_history.html

覆盖范围

  Across an entire project
  admin/change_form.html
  Across an application
  admin/<my_app>/change_form.html
  For an individual model
  admin/<my_app>/<my_model>/change_form.html

例如:

{% extends "admin/change_list.html" %}
{% block object-tools %}
    <h1 class="errornote">
        Look Here!
    </h1>
    {{ block.super }}
{% endblock %}

自定义模板的建议:

  Extend, don't override
  Use {{ block.super }} to extend blocks
  Extend a symlink of the admin templates in the event of recursion
  Extend the extrahead block in base.html for admin-wide media

已有项目:

http://code.google.com/p/sorl-curator/
http://code.google.com/p/django-grappelli/

ModelAdmin/ModelForm Hacking

注册ModelAdmin

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from demo_app.models import UserProfile
class UserProfileInline(admin.TabularInline):
    model = UserProfile
    fk_name = 'user'
    max_num = 1
class CustomUserAdmin(UserAdmin):
    inlines = [UserProfileInline, ]
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

行级别的权限

class ArticleAdmin(admin.ModelAdmin):
  def save_model(self, request, obj, form,
                                         change):
    obj.user = request.user
    obj.save()
  def queryset(self, request):
    qs = self.model._default_manager.filter(user=request.user)
    return qs

ModelForm

class AuthorForm(forms.ModelForm):
    exclude_states = ['AS', 'GU', 'MP', 'VI',]
    def __init__(self, *args, **kwargs):
        super(AuthorForm, self).__init__(*args,
                                      **kwargs)
        w = self.fields['state'].widget
        choices = []
        for key, value in w.choices:
            if key not in self.exclude_states:
                choices.append((key, value))
        w.choices = choices
class AuthorAdmin(admin.ModelAdmin):
    form = AuthorForm

Custom Views

Custom View URL

class PostAdmin(admin.ModelAdmin):
    def my_view(self, request):
        return admin_my_view(request, self)
    def get_urls(self):
        urls = super(PostAdmin, self).get_urls()
        my_urls = patterns('',
            (r'^my_view/$', self.my_view)
        )
        return my_urls + urls

Custom View

@permission_required('blog.add_post')
def admin_my_view(request, model_admin):
    opts = model_admin.model._meta
    admin_site = model_admin.admin_site
    has_perm = request.user.has_perm(opts.app_label /
                  + '.' + opts.get_change_permission())
    context = {'admin_site': admin_site.name,
        'title': "My Custom View",
        'opts': opts,
        'root_path': '/%s' % admin_site.root_path,
        'app_label': opts.app_label,
        'has_change_permission': has_perm}
    template = 'admin/demo_app/admin_my_view.html'
    return render_to_response(template, context,
              context_instance=RequestContext(request))

Custom View Template

{% extends "admin/base_site.html" %}
{% load i18n %}
{% block breadcrumbs %}
<div class="breadcrumbs">
    <a href="../../../">{% trans "Home" %}</a> &rsaquo;
    <a href="../../">{{ app_label|capfirst|
escape }}</a> &rsaquo;
    {% if has_change_permission %}<a
href="../">{{ opts.verbose_name_plural|
capfirst }}</a>{% else %}{{ opts.verbose_name_plural|
capfirst }}{% endif %} &rsaquo; My Custom View
</div>
{% endblock %}
{% block content %}
    <!-- do stuff here -->
{% endblock %}


Django的内置模板

base.html

<head>
    <title> {% block title %}{% endblock %} </title>
    {% block extrastyle %}{% endblock %}
    {% block extrahead %}{% endblock %}
</head>
{% load i18n %}
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
<!-- Container -->
<div id="container">
    <div id="header">
        <div id="branding">
         {% block branding %}{% endblock %}
        </div>
        {% block nav-global %}{% endblock %}
    </div>
    <!-- END Header -->
    {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}

    <!-- Content -->
    <div id="content" class="{% block coltype %}colM{% endblock %}">
        {% block pretitle %}{% endblock %}
        {% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
        {% block content %}
             {% block object-tools %}{% endblock %}
        {{ content }}
        {% endblock %}
        {% block sidebar %}{% endblock %}
        <br class="clear" />
    </div>
    <!-- END Content -->

    {% block footer %}<div id="footer"></div>{% endblock %}
</div>
<!-- END Container -->

</body>

base_site.html

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

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

{% block branding %}
<h1 id="site-name">
    {% trans 'Customized Admin' %}
</h1>
{% endblock %}

{% block dashboard %}

{% endblock %}

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

已有项目的调研

grappelli 用起来挺不错的。尤其是那个bookmarks很有用。至于navigation,感觉应该添加到每一个app的首页。

你可能感兴趣的:(django,admin)