Dado um modelo do Django, estou tentando listar todos os seus campos. Eu já vi alguns exemplos disso usando o atributo _meta model, mas o sublinhado na frente da meta não indica que o atributo _meta é um atributo privado e não deve ser acessado diretamente? ... Porque, por exemplo, o layout do _meta pode mudar no futuro e não ser uma API estável?
_Meta é uma exceção a esta regra? É estável e pronto para uso ou é considerado uma má prática acessá-lo? Ou existe uma função ou alguma outra maneira de examinar os campos de um modelo sem usar o atributo _meta? Abaixo está uma lista de alguns links mostrando como fazer isso usando o atributo _meta
Qualquer conselho é muito apreciado.
campo get / set do objeto django
Respostas:
_meta
é privado, mas é relativamente estável. Há esforços para formalizá-lo, documentá-lo e remover o sublinhado, o que pode ocorrer antes de 1.3 ou 1.4. Eu imagino que serão feitos esforços para garantir que as coisas sejam compatíveis com versões anteriores, porque muitas pessoas já a usam de qualquer maneira.Se você estiver particularmente preocupado com a compatibilidade, escreva uma função que use um modelo e retorne os campos. Isso significa que, se algo mudar no futuro, você precisará alterar apenas uma função.
Eu acredito que isso retornará uma lista de
Field
objetos. Para obter o valor de cada campo da instância, usegetattr(instance, field.name)
.Atualização: os colaboradores do Django estão trabalhando em uma API para substituir o objeto _Meta como parte de um verão de código do Google. Veja:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
fonte
model._meta.many_to_many
!django/core/management/commands/loaddata.py
usa _meta para percorrer a árvore de aplicativos, modelos e campos. Bom padrão a seguir ... e você pode apostar que é o "caminho oficial"._meta.virtual_fields
_meta
é agora, a API compatível formais (novo no Django 1.8)Eu sei que este post é muito antigo, mas eu só queria dizer a quem está procurando a mesma coisa que existe uma API pública e oficial para fazer isso:
get_fields()
eget_field()
Uso:
https://docs.djangoproject.com/en/1.8/ref/models/meta/
fonte
get_fields()
docs.djangoproject.com/en/1.10/ref/models/meta/…_meta
?Agora existe um método especial - get_fields ()
Ele aceita dois parâmetros que podem ser usados para controlar quais campos são retornados:
include_parents
True por padrão. Recursivamente inclui campos definidos nas classes pai. Se definido como False, get_fields () procurará apenas campos declarados diretamente no modelo atual. Os campos de modelos que herdam diretamente de modelos abstratos ou classes de proxy são considerados locais, não no pai.
include_hidden
Falso por padrão. Se definido como True, get_fields () incluirá campos usados para apoiar a funcionalidade de outros campos. Isso também inclui todos os campos que possuem um_nome relacionado (como ManyToManyField ou ForeignKey) que começam com um "+"
fonte
get_fields()
retorna aetuple
cada elemento é umModel field
tipo, que não pode ser usado diretamente como uma string. Então,field.name
retornará o nome do campomy_model_fields = [field.name for field in MyModel._meta.get_fields()]
O código acima retornará uma lista contendo todos os campos nome
Exemplo
fonte
Isso é feito pelo próprio Django ao criar um formulário a partir de um modelo. Ele está usando o atributo _meta, mas, como observou Bernhard, ele usa _meta.fields e _meta.many_to_many. Olhando para django.forms.models.fields_for_model, é assim que você pode fazer:
fonte
Os campos de modelo contidos por _meta são listados em vários locais como listas dos respectivos objetos de campo. Pode ser mais fácil trabalhar com eles como um dicionário em que as chaves sejam os nomes dos campos.
Na minha opinião, esta é a maneira mais irredundante e expressiva de coletar e organizar os objetos de campo do modelo:
(Consulte Este exemplo de uso em django.forms.models.fields_for_model.)
fonte
Que tal este.
fonte
many_to_many
evirtual_fields
.Conforme a documentação do django 2.2, você pode usar:
Para obter todos os campos:
Model._meta.get_fields()
Para obter um campo individual:
Model._meta.get_field('field name')
ex.
Session._meta.get_field('expire_date')
fonte
Se você precisar disso para o seu site de administração , também existe o
ModelAdmin.get_fields
método ( docs ), que retorna olist
nome do campostrings
.Por exemplo:
fonte
Outra maneira é adicionar funções ao modelo e, quando você deseja substituir a data, pode chamar a função.
fonte