【问题标题】:django-admin formfield_for_* change default value per/depending on instancedjango-admin formfield_for_* 根据实​​例更改默认值
【发布时间】:2011-02-26 23:06:31
【问题描述】:

我正在尝试更改外键表单字段的默认值以设置其他模型的值取决于登录的用户时间>。 但我正在为此绞尽脑汁......

这个: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"] ... 不存在。

提前致谢,尼克

【问题讨论】:

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


    【解决方案1】:

    我认为db_field.formfield 方法(也由管理员调用)总是用模型中指定的默认值覆盖您的初始值! 所以需要自己指定正确的表单域:

    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 Django: How to get current user in admin forms关于如何让当前用户对象进入表单!

    【讨论】:

    • 第一:谢谢!第二:我用 formfield_for_dbfield 试了一下,但是: ---- user = kwargs.get("request", None) 我得到了一个 -> "global name 'request' is not defined" ---- and with : field = super(EmployeeAdmin, self).formfield_for_dbfield(db_field, **kwargs) field.user = kwargs.get('request', None).user i got -> 'NoneType' object has no attribute 'user'跨度>
    • 我不确定 formfield_for_dbfield 是否会覆盖它,因为 formfield_for_foreignkey 会被调用(code.djangoproject.com/browser/django/trunk/django/contrib/… - 第 101 行)
    • 你是对的,但我的意思是它被FIELD的formfield方法覆盖,该方法在之后调用(来自管理员的方法第155行)!
    • 好的,非常感谢,代码现在可以编译,但我仍然没有得到正确的效果:-/ kwargs['initial'] 是正确的吗?
    • 您的代码中唯一的问题是,每次我实现 我都会得到一个 <__init__ got an unexpected keyword argument request> @ /usr/lib/python2.6/dist-packages/django/forms/models.py 在 init,第 937 行
    【解决方案2】:

    好的,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)
    

    抱歉给您带来压力,感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2020-12-13
      相关资源
      最近更新 更多