web-dev-qa-db-ja.com

Djangoモデルフィールドを内省する方法は?

フィールドの名前とモデルの名前(両方ともプレーン文字列)しかわからないときに、モデル内のフィールドのクラス情報を取得しようとしています。どのようにして可能ですか?

モデルを動的にロードできます。

from Django.db import models
model = models.get_model('myapp','mymodel')

今、私はフィールドを持っています-'myfield'-どうすればそのフィールドのクラスを取得できますか?

フィールドがリレーショナルの場合-関連フィールドを取得する方法は?

本当にありがとう!

36
Evgeny

モデルの_meta属性を使用してフィールドオブジェクトを取得でき、フィールドから関係などを取得できます。部門テーブルへの外部キーを持つ従業員テーブルを考えてみましょう

In [1]: from Django.db import models

In [2]: model = models.get_model('timeapp', 'Employee')

In [3]: dep_field = model._meta.get_field_by_name('department')

In [4]: dep_field[0].target_field
Out[4]: 'id'

In [5]: dep_field[0].related_model
Out[5]: <class 'timesite.timeapp.models.Department'>

django/db/models/options.pyから

def get_field_by_name(self, name):
    """
    Returns the (field_object, model, direct, m2m), where field_object is
    the Field instance for the given name, model is the model containing
    this field (None for local fields), direct is True if the field exists
    on this model, and m2m is True for many-to-many relations. When
    'direct' is False, 'field_object' is the corresponding RelatedObject
    for this field (since the field doesn't have an instance associated
    with it).

    Uses a cache internally, so after the first access, this is very fast.
    """
73
Anurag Uniyal

get_field_by_nameを使用するというAnuragUniyalからの回答は、get_field_by_nameが非推奨になったため、現在(5年後)古くなっています。 Djangoは次のヒントを提供します:

RemovedInDjango110Warning: 'get_field_by_nameは、非推奨となった非公式のAPIです。 'get_field()'に置き換えることができる場合があります

get_fieldのAPIドキュメントは ここ です。

8
tobltobs

Djangoモデルオブジェクトのすべてのフィールドを表示したい場合は、クラス(またはインスタンス化されたモデルオブジェクト)で._meta.get_fields()を呼び出してリストを取得するだけで内部を調べることができますこのAPIは、最新バージョンのDjangoで最新のものです。

例:

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

これにより、すべてのモデルフィールドのタプルが返されます。ドキュメントは見つかります [〜#〜] here [〜#〜]

2
Colton Hicks

Django.db.models.loading.get_model()はDjango 1.9で削除されました。代わりにDjango.appsを使用することになっています。

'get_field_by_nameは、Django 1.10で非推奨になった非公式のAPIです。'get_field()'に置き換えることができる場合があります。

>>> from Django.apps import apps
>>> from polls.models import Question
>>> QuestionModel = apps.get_model('polls','Question')
>>> QuestionModel._meta.get_field('pub_date')
>>> QuestionModel._meta.get_fields()
(<ManyToOneRel: polls.choice>, <Django.db.models.fields.AutoField: id>, <Django.db.models.fields.CharField: question_text>, <Django.db.models.fields.DateTimeField: pub_date>) 

問題へのリンク

1
Gambitier