2009-03-18 36 views
17

私は2つのテーブルの間に多対多の関係を持っています。 私はこの関係をDomainsクラスに定義しました。 したがって、管理インタフェースでは、ドメインを表示しているときにユーザーが表示されます。 しかし、ユーザーを表示しているときにドメインが表示されません。 これをどうすれば実現できますか?多対多関係のDjango管理フォーム

答えて

4

あなたが探しているものはInlineModelAdminだと思います。

+0

おそらく、OPが望んでいたものではないでしょう(関係のいずれかの側から通常のManyToManyフィルタセレクタを使用する方法)が、これも私が使用する解決策です。 –

+3

関係テーブル(私の場合はDomains_User)を参照する方法 明示的な中間テーブルがありません。この場合、どのようにManyToManyRelationshipのInlineModelAdminを使用するのですか –

8

組み込みの唯一の方法はInlineModelAdminですが、カスタムModelFormを使用してUser ModelAdminでこの目的のフィールドを作成することができます。簡単な設定については、以下のコードを参照してください(users = ManyToManyField(related_name='domains')と仮定)。

### yourapp/admin.py ### 

from django import forms 
from django.contrib import admin 
from django.contrib.auth.models import User 
from django.utils.translation import ugettext_lazy as _ 
from django.contrib.admin.widgets import FilteredSelectMultiple 

from .models import Domain 

class DomainAdmin(admin.ModelAdmin): 
    filter_horizonal = ('users',) 

class UserAdminForm(forms.ModelForm): 
    domains = forms.ModelMultipleChoiceField(
     queryset=Domain.objects.all(), 
     required=False, 
     widget=FilteredSelectMultiple(
      verbose_name=_('Domains'), 
      is_stacked=False 
     ) 
    ) 

    class Meta: 
     model = User 

    def __init__(self, *args, **kwargs): 
     super(UserAdminForm, self).__init__(*args, **kwargs) 

     if self.instance: 
      self.fields['domains'].initial = self.instance.domains.all() 

    def save(self, commit=True): 
     user = super(UserAdminForm, self).save(commit=False) 

     user.domains = self.cleaned_data['domains'] 

     if commit: 
      user.save() 
      user.save_m2m() 

     return user 

class UserAdmin(admin.ModelAdmin): 
    form = UserAdminForm 

admin.site.register(Domain, DomainAdmin) 
admin.site.unregister(User) 
admin.site.register(User, UserAdmin) 
+1

これは、私の場合は「ユーザー」ではなく「ユーザー」を追加するときにはうまくいかなかったのです。私は '__init__'メソッドで' self.instance.id'をチェックする必要がありました。新しいオブジェクトを 'save()'してからドメインを割り当てる必要がありました。 – alalonde

14

私は、これは古いスレッドですが、これはGoogleで上がってきた私は、より良い答えが必要だと思った最初の結果であったことを知っています。 this django bug report経由

は、私はあなたのManyToManyFieldは、両方のモデル上に表示していするための最良の方法を見つけました:

class Test1(models.Model): 
    tests2 = models.ManyToManyField('Test2', blank=True) 

class Test2(models.Model): 
    tests1 = models.ManyToManyField(Test1, through=Test1.tests2.through, blank=True) 

私はそれを自分自身をテストし、結果に非常に満足しています。まだこれにぶつかる人のために

+0

呼び出されたときにTest2が定義されていないため、ロジックのように見えるエラーメッセージ "Test2"が定義されていません。あなたの解決策は、たとえ働いていても明るいでしょう – Timo

0

、それはそれは、すでに他のアプリで定義されているModelAdminsで双方向の多対多のフィールドを注入するためのメカニズムを提供しhttps://github.com/kux/django-admin-extend

をチェックする価値があるかもしれません。