【问题标题】:Access Django model's fields using a string instead of dot syntax?使用字符串而不是点语法访问 Django 模型的字段?
【发布时间】:2012-03-11 20:42:58
【问题描述】:

在 Django 中,我可以这样做:

test = Test.objects.get(id=1)
test.name

我希望能够使用动态生成的字符串访问属性,如下所示:

test['name']

或者,使用字符串的任何其他语法。我试过了

test._meta.get_field_by_name('name')

但这会返回字段本身而不是值。

有什么想法吗?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    可以使用python内置的getattr()函数:

    getattr(test, 'name')
    

    【讨论】:

    • 一分钟太慢了!不应该花时间来测试它;)
    • 啊,我什至不必使用 Django 功能,而且我学到了一些关于 Python 的新东西。感谢您的帮助。
    • 适用于 ForeignKey?
    • 有谁知道我们如何在所述模型的内部类方法中调用它......self.getattr(SelfModelName, 'id') = ??
    • 有点晚了,不过你可以用 getattr(self, 'id')
    【解决方案2】:

    假设 name 是您实例上的一个属性 test getattr(test, 'name') 应该返回相应的值。或test.__dict__['name']

    您可以在此处阅读有关getattr() 的更多信息:http://effbot.org/zone/python-getattr.htm

    【讨论】:

      【解决方案3】:

      其他答案仍然有效,但现在您可以使用 Django 的 _meta.get_field() 来做到这一点。

      test._meta.get_field('name')
      

      请注意,Model _meta API 从 1.8 开始已开始其官方支持和 documentation,但已在其官方文档之前的早期版本中分发和使用。

      【讨论】:

      • 这仍然返回字段本身,并且 OP 对字段的值感兴趣。
      【解决方案4】:

      在 Python 中,您通常可以访问具有 dict 方法的对象中的值。

      假设你有这个类:

      class Dog(object):
          def __init___(self, color):
              self.color = color
      

      然后我实例化它:

      dog = Dog('brown')
      

      所以我可以通过以下方式看到颜色:

      print dog.color
      

      我也可以通过以下方式看到颜色:

      print dog.__dict__['color']
      

      我可以设置颜色:

      print dog.__dict__['color'] = 'green'
      
      print dog.color
      
      >>>green
      

      【讨论】:

      • 它会起作用,但一般来说,如果可能的话,您希望避免使用带下划线的属性/方法。这是一个信号,表明它们是易变的(随时可能被完全删除或固有地更改,没有警告)或出于其他原因不打算成为公共接口的一部分。有时您必须这样做,但在这种情况下,getattr 可用,因此是正确的选择。
      • @ChrisPratt 单下划线、双下划线和带有尾随双下划线的双下划线之间是有区别的。虽然您所说的(或多或少)适用于前两者,但 method 暗示它是内置的,并不表示任何隐私或保护,并且您通常在其中进行运算符重载和初始化。 docs.python.org/reference/datamodel.html#specialnamessiafoo.net/article/57stackoverflow.com/questions/1301346/…
      • @ashwoods: 是的,但即便如此,它们的使用一般都包含在inside另一个类中,所以它有点像使用内部代码的内部代码情况。最终,您通常不会只在其他仍然将特定实现远离“公共”接口的类中随意使用此类方法。
      • @ChrisPratt,在这一点上这都是相当学术的,但如果你参考 Python in a Nutshell 第二版的第 84 页,他描述了这种行为。他说,“在类体中创建的类属性、通过分配属性在体外部或通过显式绑定 C.__dict__ 中的条目在体外部创建的类属性没有区别。也就是说,我同意 getattr 可能是正确的在这种情况下的解决方案,但这并不意味着不能使用类主体外部的 dict 内部或任何其他双下划线方法。
      猜你喜欢
      • 2014-02-09
      • 1970-01-01
      • 2022-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      相关资源
      最近更新 更多