2011-12-26 13 views
0

私は主にユーザーが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'} 

アプリをインストールした後、私が影響を受けたモデルの各インスタンスからdropcodeを取得することができるようにしたい:

image_instance1.dropcode -> drop_img 
image_instance2.dropcode -> drop_img 

user_instance1.dropcode -> drop_user 
user_instance2.dropcode -> drop_user 

私はただ単に、DRを使用することができますその方法opcodeをjQuery経由で返し、適切なモデルを選択してください

これは可能ですか?私がしたいことを達成するためのより良い方法はありますか?

+0

ところで、私が作成したアプリには今はモデルがありません。 ajaxリクエストを処理するためのビューがたくさんあります。taggitアプリケーションを使用するタグを格納するためです。 – marue

答えて

0

私は以下のソリューションに来たシモンとはBurhanのヒントに基づいて:私は設定に影響を受けたモデルを定義し、それらのモデルに基本クラスとしてDragToTagableクラスを追加したがっdroppable_models設定を排除することができます。そのモデル、または私のプロジェクトの他のモデルにアプリの機能を適用するために行われる必要があることを、すべてのザッツ

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の提案のように追加のテーブルを作成する必要はありません。また、アプリは完全に独立しており、既存のモデルを実装する必要はありません。

ヒントをお願いします。

0

アプリケーションはすべてのモデルで動作する必要がある場合は、あなたが使用する必要がありますcontentypes framework

Djangoは を提供し、あなたのDjangoで作られたプロジェクトにインストール モデルのすべてを追跡することができcontenttypesのアプリケーションを含み、あなたのモデルを扱うためのハイレベルな汎用インターフェースです。

これを実装すると、アプリケーションを汎用にすることができます。これはインストールされているすべてのモデルで動作します。

EDIT:

ここ

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) 
+0

お返事ありがとうございます。私はcontenttypesのフレームワークについて知っていて、すでにそれを使うべきだと思っていました。しかし、私は何をしたいかを達成するためにそれを使用する方法の周りに私の頭脳をラップすることはできません...ヒントを開始するには? – marue

+0

まあ、それは私がdjangoのドキュメントに来た限りです。しかし、私はいずれにしてもそのモデルが必要です。 taggitアプリを使用してタグを保存するので、新しいモデルを作成しない方がよいでしょう。私のアプリはデータを保存する必要はなく、既存のアプリケーション間にいくつかのリンクを作成するだけで済みます。 – marue

+0

リンクを作成する場合は、リンクを保存する唯一の方法はモデルを使用することです。私はtaggitに慣れていませんが、他のタグアプリケーションのようなものなら、どこかのコンテンツタイプを使用していると確信しています。おそらくあなたはそれをカスタマイズすることができますか? –

0

dropcodeプロパティを適切なモデルに追加してみませんか?例えば。

from django.contrib.auth.models import User 
class UserMixin: 
    dropcode = property(lambda self: "drop_user") 
User.__bases__ += (UserMixin,) 

次に、あなたのテンプレートに:あなたは、(例えばUserモデルとして)models.pyを編集し、独自のアプリケーションの1のmodels.pyに、このようなコードを追加することはできません既存のモデルについては

class Image(models.Model): 
    .... 
    dropcode = property(lambda self: "drop_img") 

ifタグを使用して、アイテムにドロップコードがあるかどうかを確認します。

<div class="droppable"{% if item.dropcode %} dropcode="{{item.dropcode}}"{% endif %}>{{item}}</div> 
+0

再利用可能なアプリの意図が他のアプリを変更しないように、提案は機能しません。再利用可能なアプリケーションは、メインのurl.py、settings.py、およびテンプレートに変更が必要です。第2の提案は正確に何をしていますか?私はそれがとにかく解決策になると思います。 – marue

関連する問題