django-admin formfield_for_* 根据示例更改默认值

n1bvdmb6  于 2023-10-21  发布在  Go
关注(0)|答案(2)|浏览(97)

我试图改变一个foreignkey-formfield的 default value,以设置一个其他模型的Value *,具体取决于 * 登录的 * 用户 *。但我在绞尽脑汁...
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”].没有发现
谢谢你,尼克。

siotufzp

siotufzp1#

我认为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,但你可以在Django: How to get current user in admin forms中看到我的黑客如何将当前用户对象导入表单!

mwg9r5ms

mwg9r5ms2#

好吧,kwargs初始化的东西工作的整个时间,但它只是给予一个该死的,如果你给予它一个对象(就像我做的: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)

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

相关问题