场景:包含许多第三方应用的大型项目。想要为这些应用添加标记,而无需修改应用的来源。
我的第一个想法是首先在settings.py中指定模型列表(如['appname.modelname',]
,并在每个模型上调用django-tagging的register
函数。注册函数添加TagField和自定义管理器到指定的模型。该方法的问题是该函数需要在生成数据库模式之前运行。
我尝试直接在register
中运行settings.py
函数,但我需要django.db.models.get_model
才能从一个字符串中获取实际模型引用,而我似乎无法从settings.py
- 无论我尝试什么,我都会得到一个ImportError。但tagging.register
函数导入OK。
所以我改变了策略并在一个空的应用程序中编写了一个自定义管理命令。问题是挂钩到syncdb的唯一信号是post_syncdb
,这对我来说是无用的,因为它在生成数据库模式后触发。
目前我能想到的另一种方法是生成并运行类似数据库模式迁移的“南方”。这似乎更像是一个黑客而不是一个解决方案。
这似乎应该是一个非常普遍的需求,但我找不到一个干净的解决方案。
所以我的问题是:是否有可能在生成模式之前动态地向模型添加字段,但更具体地说,是否可以在不编辑源代码的情况下将标记添加到第三方模型。
为了澄清,我知道可以在模型上没有TagField的情况下创建和存储标签,但是这种方法存在一个主要缺陷,即难以同时创建和标记新模型。
答案 0 :(得分:1)
来自文档:
您无需注册模型 为了与标签一起使用它们 应用程序 - 许多功能 通过注册添加的只是 周围的便利包装 标记和标记提供的API TaggedItem模型及其经理, 如下文所述。
请查看API文档以及以下示例,了解如何向系统中的任意对象添加标记。
<强>更新强>
#views.py
def tag_model_view(request, model_id):
instance_to_tag = SomeModel.objects.get(pk=model_id)
setattr(instance_to_tag, 'tags_for_instance', request.POST['tags'])
...
instance_to_tag.save()
...returns response
#models.py
#this is the post_save signal receiver
def tagging_post_save_handler(sender, instance, created):
if hasattr(instance, 'tags_for_instance'):
Tag.objects.update_tags(instance, instance.tags_for_instance)