如何在django admin多选字段中自定义显示和自动选择?

时间:2010-04-23 04:17:19

标签: django-models django-admin django-forms

我是django的新手,所以如果我做错了,请随时告诉我。我正在尝试创建一个django订购系统。我的订单型号:

class Order(models.Model):
    ordered_by = models.ForeignKey(User, limit_choices_to = {'groups__name': "Managers", 'is_active': 1})

在我的管理员中任何用户都可以输入订单,但ordered_by必须是“经理”组中的某个人(这是我想要的行为)。

现在,如果登录用户恰好是管理员,我希望它自动用该登录用户填写该字段。我通过以下方式完成了这项工作:

class OrderAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "ordered_by":
        if request.user in User.objects.filter(groups__name='Managers', is_active=1):
            kwargs["initial"] = request.user.id
        kwargs["empty_label"] = "-------------"
        return db_field.formfield(**kwargs)
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

这也有效,但管理员默认将用户名作为选择框的显示。列出用户的真实姓名会很高兴。我能够做到这一点:

class UserModelMultipleChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.first_name + " " + obj.last_name
class OrderForm(forms.ModelForm):
    ordered_by = UserModelChoiceField(queryset=User.objects.all().filter(groups__name='Managers', is_active=1))

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm

我的问题:我不能同时做到这两点。如果我输入formfield_for_foreignkey函数并添加form = OrderForm来使用我的自定义“UserModelChoiceField”,它会显示好名称,但不会选择当前登录的用户。我是新手,但我的猜测是,当我使用UserModelChoiceField时,它会“删除”通过formfield_for_foreignkey传入的信息。我是否需要以某种方式使用super()函数传递此信息?或者完全不同的东西?

1 个答案:

答案 0 :(得分:0)

完全删除ModelChoiceField / ModelMultipleChoiceField子类并解除formfield_for_foreignkey方法。 request参数在子类中不可用,因此您无法获得当前用户。

然后在label_from_instance中使用formfield_for_foreignkey方法。您可以自己编写,但http://djangosnippets.org/snippets/1642/提供了一个强大的Django代码段。只需从该片段中继承该类。您可以将其放在不同的文件中并将其导入,或者只将其作为OrderAdmin写在OrderAdmin(NiceUserModelAdmin)类之上。

最后,重写formfield_for_foreignkey方法,将kwargs["initial"] = request.user.id置于if语句之外。我不认为这是必要的,我也无法以这种方式工作。

# admin.py

from django.contrib import admin
from django.contrib.auth.models import User
from (...) import Order

class NiceUserModelAdmin(admin.ModelAdmin):
    # ...

class OrderAdmin(NiceUserModelAdmin):
    # ...
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        kwargs["initial"] = request.user.id
        if db_field.name == "ordered_by":
            kwargs["empty_label"] = "-------------"
            return db_field.formfield(**kwargs)
        return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)