开发者

how to find associated Django ModelForm given the Model

开发者 https://www.devze.com 2023-02-17 14:50 出处:网络
I have dozens of Models, each with ONE associated ModelForm (whose Meta.model refers to the Model in question).

I have dozens of Models, each with ONE associated ModelForm (whose Meta.model refers to the Model in question).

E.g.

class FooModel(Model):
    pass

class FooModelForm(ModelForm):
    class Meta:
        model = FooModel

# current approach using a classmethod
FooModelForm.insert_in_model()  # does cls.Meta.model.form = cls

So, obviously, it's easy to find FooModel given FooModelForm. What I want is to know the best way to do the REVERSE: find FooModelForm when I am presented with FooModel or even the string "Foo".

Assume only one ModelForm for each model, although solutions that return multiple are fine.

My current approach is to stash the model in the form class (as shown above), but I'm interested in knowing better approaches especially ones that could compute it centrally (without the final line above).

EDIT: I've reviewed things like Django: Display Generic ModelForm or predefined form but I believe this is a simpler question than those. The Django admin code must do something along the lines of what I seek. But get_model equiv开发者_如何学编程alent for ModelForms? suggests that might be voodoo and that it would be best to just do dict['Foo']=FooModelForm or its equivalent to keep track of the association explicitly. Seems repetitious.


If you have under 20 forms, sounds like mapping out a dictionary is the easiest way. Django does this kinda thing internally too.

For ModelForms, django admin just creates them on the fly via modelform_factory, so there is no comparable method to get_model


I do see, your method is bullet proof, but requires a line in ever model def.

If you only have one ModelForm per model, you could potentially iterate through the ModelForm subclasses until you find your form.

find FooModelForm when I am presented with FooModel or even the string "Foo".

modelforms = forms.ModelForm.__subclasses__()
def get_modelform(model):
    try:
        return filter(lambda x:x.Meta.model == model, modelforms)[0] 
    except IndexError:
        print "apparently, there wasn't a ModelForm for your model"

If you want to pull the ModelForm as a string, you'll need to make sure both app_label and __name__ are correct, which means it will be easier to use get_model('app', 'model') in the function.

You could combine this with your method and automatically place an attribute on your models that point to its ModelForm.

Hook into the class_prepared signal at the top of your apps, find the corresponding ModelForm and attach it to your Model class. Hope that helps or gives you some ideas.

0

精彩评论

暂无评论...
验证码 换一张
取 消