django-admin formfield_for_ *根据实例更改每个/的默认值

时间:2010-06-02 17:59:55

标签: django django-models django-admin default-value foreign-keys

我正在尝试更改foreignkey-formfield的默认值,以根据登录的用户设置其他模型的值。 但我正在绞尽脑汁......

这个:Changing ForeignKey’s defaults in admin site可以选择更改empty_label,但我需要default_value。

#Now I tried the following without errors but it didn't had the desired effect:
class EmployeeAdmin(admin.ModelAdmin):
...
  def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    formfields= super(EmployeeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    if request.user.is_superuser:
        return formfields
    if db_field.name == "company":
        #This is the RELEVANT LINE
        kwargs["initial"]  = request.user.default_company

    return db_field.formfield(**kwargs)


admin.site.register(Employee, EmployeeAdmin)

##################################################################
# REMAINING Setups if someone would like to know it but i think
# irrelevant concerning the problem
##################################################################
from django.contrib.auth.models import User, UserManager
class CompanyUser(User):
    ...
    objects = UserManager()
    company = models.ManyToManyField(Company)
    default_company= models.ForeignKey(Company, related_name='default_company')
    #I registered the CompanyUser instead of the standard User, 
    #   thats all up and working
    ...

class Employee(models.Model):
    company = models.ForeignKey(Company)
    ...

提示:kwargs [“default”] ......不存在。

先谢谢你,尼克

2 个答案:

答案 0 :(得分:2)

我认为db_field.formfield方法(也由admin btw调用)总是用模型中指定的默认值覆盖你的初始值! 因此,您需要自己指定正确的表单字段:

from django import forms

class EmployeeAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, **kwargs):
        user = kwargs['request'].user
        if db_field.name == "company":
            kwargs['initial'] = user.default_company
            qs = Company.objects.all()
            return forms.ModelChoiceField(queryset=qs, **kwargs)
        return super(EmployeeAdmin, self).formfield_for_dbfield(db_field, **kwargs)

您也可以在自定义表单的 init 中进行此自定义,但问题是,您无法正常访问表单类中的request,但您可以在此处查看我的hack { {3}}关于如何将当前用户对象放入表单中!

答案 1 :(得分:0)

好吧,kwargs ['initial']的东西在整个过程中起作用,但是如果你给它一个对象(就像我做的那样:kwargs ['initial'] = user.default_company)它只是给了一个该死的。但它正在使用整数。

我解决了这个问题:

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    formfields= super(EmployeeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    if request.user.is_superuser:
        return formfields

    if db_field.name == "company":
        qs= request.user.company.all()
        #determine the default pos of configured default_company
        for index, item in enumerate(qs):
            if item==request.user.default_company:
                kwargs["initial"]  = index+1
                break
        #restrict shown entries in the ModelChoiceField
        kwargs["queryset"] = qs


    return db_field.formfield(**kwargs)

对不起有压力,感谢您的帮助!