Django - Como gerar um formulário para um modelo não conhecido com antecedência por causa da instância do contentType

StackOverflow https://stackoverflow.com/questions/4616735

Pergunta

Eu tenho o seguinte modelo e sua forma:

class Project(models.Model)

class ProjectForm(forms.ModelForm)
    class Meta:
        Model = Project

Portanto, é fácil criar um formulário instantando:

form = ProjectForm()

Mas, no meu caso, tenho vários modelos além dos "projetos" e não sei com antecedência qual desses modelos precisarei criar o formulário.

Então, eu gostaria de criar o formulário a partir da instância do ContentType do modelo do projeto.

Em outras palavras, estou procurando algo que se parece:

myproject = Project()
form = createform(myproject.ContentType)
Foi útil?

Solução

Presumivelmente, você tem uma certa seleção limitada de modelos que podem ser usados. A maneira mais simples é apenas criar classes de formulário para cada uma delas e escolher a necessária de um dicionário:

MODEL_FORMS = {
    MyModel: MyModelForm,
    MyOtherModel: MyOtherModelForm
}

my_form_class = MODEL_FORMS[my_project.content_type]
my_form = my_form_class()

Outras dicas

Infelizmente, este foi o melhor que pude encontrar - mas uma combinação de get_model e form_for_model deve fazer o truque. Você precisará usar get_model Para carregar o tipo de modelo em que você deseja trabalhar e depois form_for_model Para obter um formulário para esse modelo.

Editar: A solução de Daniel é muito melhor se você souber com quais modelos está lidando.

Obrigado a vocês dois, isso ajuda muito!

Eu irei com a solução de Daniel, pois tenho um número limitado de modelos.

Acho que talvez precise adicionar model_class () a "my_project.content_type.model_class ()" para obter a classe Model (a ser verificada)?

Apenas para o registro, eu consegui fazer algo funcionar com as fábricas de formulário de modelo:

from django.forms.models import modelformset_factory
ProjectFormSet = modelformset_factory(my_project.content_type.model_class())
my_form = ProjectFormSet()

Mas esse formulário, obviamente, não receberia todas as personalizações feitas nos meus formulários de modelo ... então essa não era uma boa solução.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top