动态更新ModelForm的Meta类模型字段

2 投票
4 回答
1065 浏览
提问于 2025-04-15 19:07
def SiteAdminForm(model_cls, *args, **kwargs):
    class MerchantAdminForm(forms.ModelForm):
        class Meta:
            exclude = ('external_links', 'published', 'logo','image_zip_file',)
            model = model_cls

        def __init__(self, *args, **kwargs):
            super(MerchantAdminForm, self).__init__(*args, **kwargs)

    return MerchantAdminForm()

# In use...
merchant_form = SiteAdminForm(merchant.__class__, instance=merchant)

无论传入什么内容到 model_cls,模型总是被忽略。

Meta.exclude 设置得很好,那我该如何动态更新 Meta.model 呢?

4 个回答

0

这是因为你的 merchant.__class__ 实际上是 django.db.models.base.ModelBase。如果你只是尝试打印 merchant,你会得到正确的类路径(我得到的是 app.models.TestModel),但是 BaseModel。

我认为这是因为使用了元类。可能是元类把对象的类设置成了 ModelBase。Django 广泛使用这个 Python 特性,这可能会导致一些奇怪的行为(对那些不太理解的人来说,像我一样觉得奇怪;并不是说它不工作)。我会尝试看看 Django 的代码——你也可以去看看 :-)

无论如何,你在表单中得到了你想要的东西,它应该能正常工作 :-)

真是的

当然我知道为什么会这样。你是在询问一个类的类。你知道的,form.Meta.model 里面是一个类,就是你传给表单的那个。这就是你得到 ModelBase 的原因——你得到了元类。

值得去了解一下元类,因为它们很酷。不过它们也有点复杂 ;-) 在这里你可以阅读相关内容。

0

我真是个傻瓜,想了一晚上,第二天再看就几乎立刻明白了!!!

原来 return MerchantAdminForm() 应该写成 return MerchantAdminForm(*args, **kwargs)

4
def get_form(model_class):
    class DynamoForm(forms.ModelForm):
        class Meta:
            model = model_class

    return DynamoForm


form_set = get_form(ActualModel)(request.POST)

这就是你想要的吗?

撰写回答