django admin - 用callable填充字段

时间:2011-06-26 14:49:29

标签: python django django-admin

除了这个例子之外,我找不到任何人这样做的例子,除了知道代码需要在哪里之外,这对我没什么帮助。

How to prepopulate UserProfile fields in the Django admin?

所以这是我的代码

class QuoteMaterial(models.Model):
    name = models.CharField(_('name'), max_length=255)
    content = models.TextField(_('content'),
                           help_text=_('A static priced item used when doing a job. Selectable when creating a quote. '))
    price = models.DecimalField(_('price'), max_digits=6, help_text="not sure if this is before or after VAT yet", decimal_places=2, default="0.00")

    def get_companies():
        return CompanyProfile.objects.filter(user=request.user)

    company = models.ForeignKey(CompanyProfile, default=get_companies) 

如果不是很明显,我会在管理部分尝试使用属于已登录用户的可用公司填充下拉列表。

我的问题是我不知道如何将请求对象传递给“get_companies”。任何人都知道任何例子。

2 个答案:

答案 0 :(得分:3)

您必须在扩展ModelAdmin的管理类中覆盖,而不是在扩展models.Model的类中。具体来说,您需要覆盖formfield_for_foreignkey

来自the docs

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "car":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
    return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

对于你的情况,它看起来像是:

if db_field.name == "company":
    kwargs['queryset'] = request.user.company_set.all()

答案 1 :(得分:0)

你正在混淆条款。

“预先填充”表示从另一个字段填写字段。这不是你为管理弹出窗口过滤的方式,因为你实际上并没有设置字段,只是限制选择并让用户设置字段。

另外,字段的default值必须是常量,因为它会传递给数据库,而数据库不能使用查询来设置默认值。

您真正想要的内容类似于limit_choices_to的{​​{1}}(docs)参数,但即便如此,您也无法使用{{ 1}}为此;它必须使用模型中的字段。这样做的原因是,如果您将其基于用户,则某些用户将无法选择其他用户设置的当前值。当用户只想更改ForeignKey时,您不希望request更改自身,例如,因为company不会在过滤器中产生当前content