2011-04-02 9 views
1

自分のプロジェクトに再利用可能なアプリがいくつかあります。アプリの間でDjangoの管理者がインラインで共有する

まず、コンテンツコンテンツをContentContainerに追加する方法を定義する基本コンテンツAppがあります。これにより、他のモデルはContentContainerを継承してコンテンツを表示することができます。

コンテンツアプリ内で、私はContentContainerを継承するPageモデルを持っています。イベントと呼ばれる別のアプリケーションでは、私はContentContainerも継承するイベントモデルを持っています。基本的には、私のイベントアプリは私のコンテンツアプリに依存しています(これは私が欲しいものです)。

これはすべてモデリングに優れています。私は私のコンテンツアプリでこれを持っている:

class ContentContainer(admin.ModelAdmin): 
    #No fields, it just gets referred to by ContentItem 

    class Meta: 
     ordering = ['modified'] 

class ContentItem(TimeStampedModel): 
    name = models.CharField(max_length=1500) 
    page_order = models.IntegerField() 
    container = models.ForeignKey(ContentContainer, blank=True) 

    #make inheritance know the model type 
    objects = InheritanceManager() 

    class Meta: 
     ordering = [ 'page_order', 'modified', 'name'] 

    def __unicode__(self): 
     return self.name 

    def render(self): 
     return self.name 


class TextContent(ContentItem): 
    text = models.CharField(max_length=5000000) 

    def render(self): 
     return '<p>%s</p>' % self.text 

はその後、私のイベントのアプリで、私はこれを行う:

class Event(AnnouncementBase, Addressable, ContentContainer): 
    cost = CurrencyField(decimal_places=2, max_digits=10, blank=True, default=0.00) 
    start_date = models.DateField(default = datetime.now().date()) 
    start_time = models.TimeField(default = datetime.now().time()) 
    end_date = models.DateField(blank=True, default=None, null = True) 
    end_time = models.TimeField(blank=True, default=None, null = True) 
    rsvp_deadline = models.DateTimeField(blank=True, default=None, null = True) 

    class Meta: 
     ordering = ['start_date', 'start_time', 'title'] 

だから今のイベントがレンダリングするコンテンツを持つことができます。

ここでは混乱するところがあります。私はコンテンツアプリのadmin.pyで定義されたインラインのスルーを持っています。彼らはそこで大きく働いています。また、イベントアプリのadmin.pyに貼り付けると、彼らもそこで働いています。

しかし、私はコードを複製したくありません。私は内容ではevents.pyにadmin.pyからインラインをインポートしたい私はこれを持っているのadmin.py:これらのインライン化の束があります

class TextContentInline(admin.TabularInline): 
    model = models.TextContent 
    extra = 1 

class PageAdmin(ContainerAdmin): 
    model = models.Page 
    inlines = [LinkContentInline, TextContentInline] 

。 admin.pyモデル間でどうやって共有できますか?私がイベントadmin.pyでそれらをインポートしようとすると、 "モデルページは既に登録されています"というエラーが表示されます。私は約5つの異なるものを試しました。彼らのどれも働かないと考えることができました。私はこれをする方法がないのだろうかと思っています。ああ、私もDjango 1.3を使用しています。

+0

質問、インラインまたはPageAdminをインポートしていますか? – Jerzyk

答えて

3

モジュールがインポートされると、Pythonはトップレベルのすべてのステートメントを実行し、そのうちの1つがadmin.site.registerであるため、複数回呼び出されるため、「既に登録されています」というエラーが発生します。

それは、この問題を解決するのは簡単です - ちょうど例外をキャッチし、それを無視:

try: 
    admin.site.register(MyModel, MyModelAdmin) 
except admin.sites.AlreadyRegistered: 
    pass 

代替は、完全に独立したモジュールファイルにあなたのインラインクラスを維持することです - おそらく、admin_inlines.py - とにそこからインポートしますそれらを必要とするすべての管理者。

+0

私は、ラインラインをadmin_inlinesというファイルに移動します。 CONTENT_INLINESという定数リストを作成し、2つの管理モデルで使用するためにそれをインポートしました。このようにしてインラインを追加すると、そのインラインを一定に変更するだけです。偉大な答えをありがとう、私はそれがまだ十分な担当者を持っていない私はドンを投票するだろう。 – Jon

関連する問題