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的首页。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值