更改Django中的管理员模板

0 投票
1 回答
565 浏览
提问于 2025-04-17 16:09

我有一个简单的模型:

class Reseller(models.Model):
    type = models.CharField(
        max_length=32,
        choices=(
            ('active', 'active'),
            ('inactive', 'inactive')))
    first_name = models.CharField(max_length=64, verbose_name='First Name')
    last_name = models.CharField(max_length=64, verbose_name='Last Name')
    email = models.CharField(max_length=64, verbose_name='E-mail')
    password = models.CharField(max_length=64, blank=True, editable=False)

我为这个模型自动生成了一个管理界面,用来进行增删改查(CRUD)。我想在更新页面添加一个“重新发送密码”的按钮(这个按钮的作用是把新的登录信息发送给经销商),但我不知道该怎么做。我知道可以使用扩展功能,但不太清楚如何正确应用它。点击这个按钮后,最好能留在同一个页面,并显示一个通知,比如“新密码已发送”。

另外,我也不知道如何在Django的管理界面中处理这个新按钮的操作。如果有一些代码示例就太好了。谢谢!

更新 我创建了一个 change_form.html 文件,并扩展了原来的模板。

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

{% load i18n %}

{% block object-tools %}
{% if change %}
  <ul class="object-tools">
  <li><a href="reset_password/">Reset Password</a></li>
  </ul>

{% endif %}
{% endblock %}

但我不知道该如何处理这个HTTP请求。另外,我该如何传递参数呢?我是不是应该创建一个表单而不是按钮?

1 个回答

2

你可能需要写一个管理员操作,具体可以查看Django的文档了解更多细节。

更新:你应该创建类似这样的功能,这样你就可以对从经销商列表页面选中的一个或多个经销商执行操作。最终你会得到这样的效果:

from django.contrib import admin
from myapp.models import Reseller

class ResellerAdmin(admin.ModelAdmin):
    ...

    actions = ['reset_password']

    def reset_password(self, request, queryset):
        for obj in queryset:
            obj.password = genereate_new_passwd()
            sender.send(obj.email, obj.password)
            obj.save()
        self.message_user(request, "Passwords were resets for selected resellers successfully.")

    reset_password.short_description = "Resend Passwords for selected resellers"

admin.site.register(Reseller, ResellerAdmin)

更新 2:要在模型更改页面提供自定义操作,你需要自定义ResellerAdmin的change_view()方法,并提供一个带有自定义操作的模板。

from django.contrib import admin
from myapp.models import Reseller

change_form_template = 'admin/myapp/extras/reseller_change_form.html'

class ResellerAdmin(admin.ModelAdmin):

    def change_view(self, request, object_id, form_url='', extra_context=None):
        if(comming from new action)
            # intercept the request post here, if it comes from your new button, do reset password
        else: 
            return super(ResellerAdmin, self).change_view(request, object_id,
               form_url, extra_context=extra_context)

另一种方法是通过添加一个布尔字段来定制表单,在save_model()中检查这个字段是否为True,如果是,就重置密码并保存;否则只保存对象。在这种情况下,你不需要提供自定义模板。

class ResellerAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if change and form.is_reset:
             #do reset password and send
        obj.save()

    def get_form(self, request, obj=None, **kwargs):
        form = super(ResellerAdmin, self).get_form(request, obj, **kwargs)
        form.fields['is_reset'] = form.BooleanField()
        return form

上面的代码并不完整,但只是为了展示这个思路,关于如何自定义ModelAdmin的更多细节可以在这里找到。

撰写回答