get_model equivalent for ModelForms?
I have a multiple Model开发者_如何转开发Form classes that each represent a different Model. I would like to have a generic 'create' function that loads the specified model form based on a URL parameter. It is possible to load a model dynamically with this:
model_name = 'TestModel'
m = get_model('AppLabel', model_name)
Does anyone know how I can achieve the same for ModelForms, something like:
modelform_name = 'TestModelForm'
f = get_form('AppLabel', modelform_name)
if f.is_valid():
...
I can not think of a way to do this with generic views - they require the ModelForm to be passed, rather than just its name. If I get the model with get_model then pass that to the generic view it will display a form but I am unable to exclude model fields.
TIA for any tips
When you create a ModelForm
it does not register itself with its model's app. (Based on experience and a quick browse through the source).
Here are some otheroptions I can think of:
All
ModelForm
classes exist in a single module: Usegetattr
on that module based on the string.ModelForm
's are spread out among many models and you have a reasonable (<30) amount of forms: Create a dictionary mapping from form strings you expect to ModelForm classes. For example:from some_app.forms import FirstModelForm from another_app.forms import SecondModelForm from additional_app.forms import FirstModelForm as AdditionalAppFirstModelForm # Will allow for managing conflicting names easily. form_mapping = { 'FirstModelForm': FirstModelForm, 'SecondModelForm': SecondForm, 'AdditionalAppFirstModelForm': AdditionalAppFirstModelForm, } request_form_class = request.POST.get('form_class') f = form_mapping.get(request_form_class)(request.POST) if f.is_valid(): f.save()
You're dealing with a lot of forms: Create a baseclass for your ModelForm, or replace the
BaseModelFormMetaclass
at runtime. You'll have to deal with issues such as name conflicts, duplicateModelForm
s for the sameModel
"automagically", so prepare for some headaches. It would be pretty rad if you could pull it off.
Personally (as you can probably see), I'd just go with option #2.
An alternate method for this is to replace forms.py
with a package called forms
. Then, in __init__.py
within that package, import all your ModelForm
s.
Then you can use sdolan's Option #1.
精彩评论