【问题标题】:Override .objects in Model Django outside models.py在models.py之外覆盖模型Django中的.objects
【发布时间】:2015-05-26 12:58:09
【问题描述】:

我想覆盖 models.py 中的类以在运行时获取调用堆栈。

我知道我们可以在 Django 中执行以下操作以覆盖管理器并因此自定义 QuerySet API -

所以,在models.py

class A(models.Model):
      objects = SomeClass()

SomeClass

class B(Manager):
     def get_query_set(): 
     # override the way you want

但是,为了让事情变得更简单,我正在考虑使用装饰器来覆盖相同的东西 - 所以, 在models.py

@ decoratorForOverriding class A(models.Model): pass

decorator.py

def decoratorForOverriding(cls):
 cls.objects = SomeClass()

我得到的错误是

AttributeError: 'NoneType' object has no attribute '_meta'

知道发生了什么吗? 我应该将class A 作为抽象类吗?那也没有用。

【问题讨论】:

  • 你想达到什么目的?
  • 装饰器必须返回一些东西。在这里它应该返回修改后的类。
  • 还要注意,在 django 模型类中会发生一些黑魔法(参见 django.models.base.ModelBase,特别是 __new__() 方法),因此您的幼稚解决方案很可能无法按原样工作。
  • @JérômeThiard 也尝试过这样做。我还尝试使用functools 中的update.wrapper 进行更新,以便类属性可以保持不变。但它会产生有关Foreign Keys 的问题。 @brunodesthuilliers,是的,我只是不明白从哪里获得这些“全部”见解。能否请您指出在哪里以及如何访问django.models.base.ModelBase 数据的链接。(例如,获取 theModelBase 的类属性,在外部使用它,并返回相同的属性,以便返回的属性会“表现”所需的方式。

标签: python django django-models


【解决方案1】:

您提到您知道如何覆盖模型的Manager。我很难想象在装饰器中覆盖经理与作为财产有什么好处。正如bruno desthuilliers 在他的评论中提到的那样,Django 在实例化时使用 objects 属性做了很多事情,装饰器可能不起作用。

按照 Django 核心的意图执行此操作:https://docs.djangoproject.com/en/1.8/topics/db/managers/

否则会增加技术债务而没有真正的好处(至少据我所知)。如果有什么不能通过Manager 实现,让我们来解决这个问题。

【讨论】:

  • Francis Yaconiello,有一个巨大的现有 django 应用程序,我想在models.py 中获取类的调用堆栈,我可能不想记录所有类的调用堆栈,可能是一些。因此,在现有代码中,为了简化所谓的“元任务”,我想到了使用装饰器,这反过来又会帮助我不干扰现有代码。我的用例是 - 在运行时在 django 应用程序中获取所需类的调用堆栈。那么,为这样的任务使用装饰器是不可取的吗?
猜你喜欢
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
相关资源
最近更新 更多