web-dev-qa-db-ja.com

Djangoのモデルのフィールドを取得します

Djangoモデルを考えると、そのすべてのフィールドをリストしようとしています。 _metaモデル属性を使用してこれを行う例を見てきましたが、メタの前にあるアンダースコアは、_meta属性がプライベート属性であり、直接アクセスすべきではないことを示していませんか? ...たとえば、_metaのレイアウトは将来変更される可能性があり、安定したAPIではない可能性がありますか?

_metaはこのルールの例外ですか?安定しており、すぐに使用できますか、またはアクセスするのは悪い習慣と見なされていますか?または、_meta属性を使用せずにモデルのフィールドをイントロスペクトする関数または他の方法がありますか?以下は、_meta属性を使用してこれを行う方法を示すいくつかのリンクのリストです。

どんなアドバイスも大歓迎です。

Djangoオブジェクトのget/setフィールド

http://www.djangofoo.com/80/get-list-model-fields

Djangoモデルフィールドをイントロスペクトする方法?

102
Joe J

_metaはプライベートですが、比較的安定しています。 1.3または1.4より前に発生する可能性のある、形式化、文書化、アンダースコアの削除を行う努力があります。多くの人がとにかくそれを使用しているので、物事に後方互換性があることを保証する努力がなされると思います。

互換性について特に懸念がある場合は、モデルを取得してフィールドを返す関数を作成します。これは、将来何かが変更された場合、1つの機能を変更するだけでよいことを意味します。

def get_model_fields(model):
    return model._meta.fields

これにより、Fieldオブジェクトのリストが返されると思います。インスタンスから各フィールドの値を取得するには、getattr(instance, field.name)を使用します。

更新:Django貢献者は、Google Summer of Codeの一部として_Metaオブジェクトを置き換えるAPIに取り組んでいます。見る:
- https://groups.google.com/forum/#!topic/Django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api

134
Will Hardy

私はこの投稿がかなり古いことを知っていますが、同じことを探している人に、これを行うためのパブリックおよび公式APIがあることを伝えたいと思いました:get_fields() and get_field()

使用法:

fields = model._meta.get_fields()
my_field = model._meta.get_field('my_field')

https://docs.djangoproject.com/en/1.8/ref/models/meta/

85
PirosB3

これは、モデルからフォームを構築するときにDjango自体によって実行されるものです。 _meta属性を使用していますが、Bernhardが述べたように、_meta.fieldsと_meta.many_to_manyの両方を使用します。 Django.forms.models.fields_for_modelを見ると、次のようになります。

opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
    print '%s: %s' % (f.name, f)
8
ecstaticpeon

現在、特別なメソッドがあります- get_fields()

    >>> from Django.contrib.auth.models import User
    >>> User._meta.get_fields()

返されるフィールドを制御するために使用できる2つのパラメーターを受け入れます。

  • include_parents

    デフォルトで真。親クラスで定義されたフィールドを再帰的に含みます。 Falseに設定すると、get_fields()は現在のモデルで直接宣言されたフィールドのみを検索します。抽象モデルまたはプロキシクラスから直接継承するモデルのフィールドは、親ではなくローカルと見なされます。

  • include_hidden

    デフォルトではfalse。 Trueに設定すると、get_fields()には、他のフィールドの機能を支援するために使用されるフィールドが含まれます。これには、「+」で始まるrelated_name(ManyToManyField、ForeignKeyなど)を持つフィールドも含まれます。

6
pecos pest

_metaに含まれるモデルフィールドは、それぞれのフィールドオブジェクトのリストとして複数の場所にリストされます。キーがフィールド名である辞書としてそれらを使用する方が簡単な場合があります。

私の意見では、これはモデルフィールドオブジェクトを収集および整理するための最も冗長で表現力のある方法です。

def get_model_fields(model):
  fields = {}
  options = model._meta
  for field in sorted(options.concrete_fields + options.many_to_many + options.virtual_fields):
    fields[field.name] = field
  return fields

(Django.forms.models.fields_for_modelの この使用例 を参照してください。)

4
jxqz

get_fields()Tupleを返し、各要素はModel field型であり、文字列として直接使用することはできません。したがって、field.nameはフィールド名を返します

my_model_fields = [field.name for field in MyModel._meta.get_fields()]
上記のコードは、すべてのフィールド名を含むリストを返します


In [11]: from Django.contrib.auth.models import User

In [12]: User._meta.get_fields()
Out[12]: 
(<ManyToOneRel: admin.logentry>,
 <Django.db.models.fields.AutoField: id>,
 <Django.db.models.fields.CharField: password>,
 <Django.db.models.fields.DateTimeField: last_login>,
 <Django.db.models.fields.BooleanField: is_superuser>,
 <Django.db.models.fields.CharField: username>,
 <Django.db.models.fields.CharField: first_name>,
 <Django.db.models.fields.CharField: last_name>,
 <Django.db.models.fields.EmailField: email>,
 <Django.db.models.fields.BooleanField: is_staff>,
 <Django.db.models.fields.BooleanField: is_active>,
 <Django.db.models.fields.DateTimeField: date_joined>,
 <Django.db.models.fields.related.ManyToManyField: groups>,
 <Django.db.models.fields.related.ManyToManyField: user_permissions>)

In [13]: [field.name for field in User._meta.get_fields()]
Out[13]: 
['logentry',
 'id',
 'password',
 'last_login',
 'is_superuser',
 'username',
 'first_name',
 'last_name',
 'email',
 'is_staff',
 'is_active',
 'date_joined',
 'groups',
 'user_permissions']
4
JPG

これはどう。

fields = Model._meta.fields
2
JDE876

Django documentation 2.2に従って、次を使用できます。

すべてのフィールドを取得するには:Model._meta.get_fields()

個々のフィールドを取得するには:Model._meta.get_field('field name')

Session._meta.get_field('expire_date')

1
user10960338

adminサイトでこれが必要な場合は、ModelAdmin.get_fieldsメソッド( docs )もあります。フィールド名のliststrings

例えば:

class MyModelAdmin(admin.ModelAdmin):
    # extending change_view, just as an example
    def change_view(self, request, object_id=None, form_url='', extra_context=None):
        # get the model field names
        field_names = self.get_fields(request)
        # use the field names
        ...
0
djvg