重写Django的RelatedManager方法
Django中的ForeignRelatedObjectsDescriptor.create_manager(...)
这个函数可以动态地创建RelatedManager
类,并且会初始化这个新创建的类的实例。
如果我想要修改RelatedManager.add(...)
这个方法,我该怎么做呢?
RelatedManager
类是在这个文件中创建的:django/db/models/fields/related.py
。
我想使用自定义的RelatedManager
的一个例子是...
class Record(Model):
string = CharField()
class Managed(Model):
record = ForeignKey('Record')
boolean = BooleanField()
def view_function(...):
record = Record(string='Example')
record.save()
record.managed_set.add(Managed(boolean=True)) # How to override add()?
任何建议都非常感谢。
3 个回答
RelatedManager.add()
这个方法会调用 RelatedManager._add_items()
,而这个方法又会调用 Manager.bulk_create()
。
所以,如果你对 Manager.bulk_create()
进行扩展,可能就能实现你想要的功能。
我觉得我遇到了同样的问题。
我有一个自定义的管理器,它重写了 self._db
和 get_query_set()
,这样可以把请求导向不同的数据库。
我动态创建了一个 模型 类,并把它的 _default_manager
设置为我的自定义管理器。
这样在类本身上是有效的,但在关联字段(比如外键或多对多关系)上就不行,尽管我设置了 use_for_related_fields = True
。
对于关联字段,添加 db_manager(dbname)
(比如 record.managed_set.db_manager(dbname)
)可以解决 all() 方法的问题,但对 add() 方法就不管用了。
想要理解我说的内容,可以看看这个 Django 的问题单:http://code.djangoproject.com/ticket/13358
我觉得对 all()
有效,但对 add()
就不行。
我不太明白你为什么需要重写这个,默认的查询集已经能满足你的需求了。
不过为了回答你的问题,你可以在模型上定义一个自定义的管理器,并设置 use_for_related_fields=True
,这样它就会被用作自动管理器。你可以查看这部分的文档,了解更多关于 自动管理器类型的控制。