4

query コマンドを使用するとdefer(...)、Django は元のモデルとは異なるクラスを返します。defer フィールドを使用する場合、モデルの名前を動的に取得するにはどうすればよいですか?

コード内:

obj_nodefer = model_class.objects.filter(title="foo")[0]
model_name = str(type(obj_nodefer)) # Works just fine

obj_defer = model_class.objects.filter(title="foo").defer("content")[0]
model_name = str(type(obj_defer)) # Does't return the right name because of defer above.

からモデルの名前を取得するにはどうすればよいobj_deferですか?

4

4 に答える 4

6

__class__.__name__遅延クラスでは、次を使用して文字列を操作せずに元のクラスを取得することもできます。

obj._meta.concrete_model
'product.models.ProductModelName'

obj._meta.concrete_model._meta.app_label
'product'

obj._meta.concrete_model._meta.model_name
'productmodelname'
于 2015-11-24T15:19:44.720 に答える
4

非遅延モデルを取得するには、次のようにします。

t = type(obj)
if t._deferred:
  t = t.__base__
于 2014-01-09T23:00:29.923 に答える
0

にアクセスできます。obj.__class__

  >>> print obj.__class__
  <class 'product.models.Product_Deferred_name'>
  >>> print obj.__class__.__name__
  Product_Deferred_name
  >>> print obj.__class__.__name__.split("_")[0]
  Product

モデル名に が含まれている場合_

  >>> print obj.__class__.__name__.replace("_Deferred_name","")
  Product
于 2013-01-12T19:31:16.970 に答える
0

django 1.4 では、遅延クラスは次のように構築されます。

def deferred_class_factory(model, attrs):
    """
    Returns a class object that is a copy of "model" with the specified "attrs"
    being replaced with DeferredAttribute objects. The "pk_value" ties the
    deferred attributes to a particular instance of the model.
    """
    class Meta:
        proxy = True
        app_label = model._meta.app_label

    # The app_cache wants a unique name for each model, otherwise the new class
    # won't be created (we get an old one back). Therefore, we generate the
    # name using the passed in attrs. It's OK to reuse an existing class
    # object if the attrs are identical.
    name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs))))
    name = util.truncate_name(name, 80, 32)

    overrides = dict([(attr, DeferredAttribute(attr, model))
            for attr in attrs])
    overrides["Meta"] = Meta
    overrides["__module__"] = model.__module__
    overrides["_deferred"] = True
    return type(name, (model,), overrides)

したがって、理論的には、次のようにして実際のクラスに到達する必要があります

type(type(deferred))
于 2013-01-12T20:13:36.897 に答える