我写了一个主要允许用户通过jQuery将标签拖动到对象的应用程序。我想允许该应用程序适用于多个模型,以便我可以标记即。用户或图像。为此我想到在页面上的每个模型表示中添加一个包含“dropcode”的类:
<div class="droppable" dropcode="drop_img"> some image </div>
<div class="droppable" dropcode="drop_user"> some user </div>
我想为主项目设置中的每个模型指定“dropcode”:
droppable_models={User:'drop_user',Image:'drop_img'}
安装应用程序后,我希望能够从受影响模型的每个实例中检索丢弃代码:
image_instance1.dropcode -> drop_img
image_instance2.dropcode -> drop_img
user_instance1.dropcode -> drop_user
user_instance2.dropcode -> drop_user
这样我就可以简单地在页面上使用dropcode,通过jQuery返回它来选择合适的模型
这可能吗?有没有更好的方法来实现我想做的事情?
答案 0 :(得分:0)
如果您的应用程序适用于任何模型,那么您应该使用contentypes framework:
Django包含一个可以跟踪所有内容的contenttypes应用程序 安装在Django驱动项目中的模型,提供了一个 用于处理模型的高级通用界面。
实现这一点允许您的应用程序是通用的 - 它可以与任何已安装的模型一起使用。
编辑:
以下是如何使用内容类型框架(直接来自documentation):
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
def __unicode__(self):
return self.tag
现在,要为项目添加标记:
item = Model.object.get(pk=1)
ti = TaggedItem(tag='foo',content_object=item)
ti.save()
获取特定项目的标签:
i = Image.object.get(pk=1) # or any instance of the Image object, or any object
the_type_of_object = ContentType.objects.get_for_model(i)
# Find all tags for this object
image_tags = TaggedItem.objects.filter(content_type__pk=the_type_of_object.id,
object_id=i.id)
答案 1 :(得分:0)
为什么不在适当的模型中添加dropcode
属性?例如
class Image(models.Model):
....
dropcode = property(lambda self: "drop_img")
对于无法修改models.py
(例如User
型号)的现有模型,请将此类代码添加到您自己的某个应用的models.py
中:
from django.contrib.auth.models import User
class UserMixin:
dropcode = property(lambda self: "drop_user")
User.__bases__ += (UserMixin,)
然后在您的模板中,使用if
标记检查某个项目是否包含丢弃代码。因此,您可以取消droppable_models
设置:
<div class="droppable"{% if item.dropcode %} dropcode="{{item.dropcode}}"{% endif %}>{{item}}</div>
答案 2 :(得分:0)
根据Simon和Burhan的提示,我得出以下解决方案:我在设置中定义受影响的模型,然后将DragToTagable类作为基类添加到这些模型中。这看起来像在设置中:
DROPPABLE_MODELS=('test.TestItem:item',)
需要做的就是将应用功能应用于该模型或我项目的任何其他模型。我的应用程序的model.py现在看起来像这样:
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
try:
#perform this when starting the project
for definition in settings.DROPPABLE_MODELS:
#parse contenttype
parsed=definition.split(':')
dropcode=parsed[1]
parsed=parsed[0].split('.')
appname=parsed[0]
modelname=parsed[1]
#get the models class for the specified contenttype
model_class=ContentType(app_label=appname, model=modelname).model_class()
#create class Mixin, containing the dropcode property
class DragToTagable:
dropcode = dropcode
#add DragToTagable as a base class to the model class
model_class.__bases__+=(DragToTagable,)
except AttributeError:
pass
except:
import sys
print "Unexpected error:", sys.exc_info()[0]
raise
这样我就不必创建额外的表,就像在burhans提案中一样。该应用程序保持完全独立,无需在现有模型上实施。
感谢您的提示。