2009-08-27 17 views
11

W moim models.py mam coś takiego:Jak dodać dwukierunkowe manytomanyfields w admin django?

class LocationGroup(models.Model): 
    name = models.CharField(max_length=200) 

class Report(models.Model): 
    name = models.CharField(max_length=200) 
    locationgroups = models.ManyToManyField(LocationGroup) 

admin.py (standard):

admin.site.register(LocationGroup) 
admin.site.register(Report) 

Gdy wchodzę na stronę admina do Raportu, pokazuje piękny pole wielokrotnego wyboru. Jak mogę dodać to samo pole wyboru wielokrotnego w grupie lokalizacji? mogę uzyskać dostęp do wszystkich raportów poprzez wywołanie LocationGroup.report_set.all()

+0

pokrewne bilet: https://code.djangoproject.com/ticket/897 – guettli

Odpowiedz

8

Obejście znalazłem postępować zgodnie z instrukcjami dla ManyToManyFields with intermediary models. Nawet jeśli nie używasz funkcji modelu "przelotowego", po prostu udawaj, jakbyś był i stwórz model pośredni z niezbędnym kluczem obcym.

# models: make sure the naming convention matches what ManyToManyField would create 
class Report_LocationGroups(models.Model): 
    locationgroup = models.ForeignKey(LocationGroup) 
    report = models.ForeignKey(Report) 

# admin 
class ReportInline(admin.TabularInline): 
    model = models.Report_LocationGroups 

class LocationGroupAdmin(admin.ModelAdmin): 
    inlines = ReportInline, 
+1

Wygląda jak względnie najłatwiejsza implementacja, thx! –

+0

Najprostszy, ale wciąż hack. Chciałbym, żeby Django mógł to poprzeć w bardziej elegancki sposób. –

2

myślę yon można połączyć ten przykładowy kod (source) przerwy wich sync_db

class ItemType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    description = meta.CharField(maxlength=250) 
    properties = meta.ManyToManyField('PropertyType', 
      db_table='app_propertytype_itemtypes') 

class PropertyType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    itemtypes = meta.ManyToManyField(ItemType) 

z this snippet

class ManyToManyField_NoSyncdb(models.ManyToManyField): 
    def __init__(self, *args, **kwargs): 
     super(ManyToManyField_NoSyncdb, self).__init__(*args, **kwargs) 
     self.creates_table = False 

do uzyskania podobnie jak

class ItemType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    description = meta.CharField(maxlength=250) 
    properties = meta.ManyToManyField_NoSyncdb('PropertyType', 
      db_table='app_propertytype_itemtypes') 

class PropertyType(meta.Model): 
    name = meta.CharField(maxlength=100) 
    itemtypes = meta.ManyToManyField(ItemType) 

Zastrzeżone: jest to tylko grubsza

Edit: Nie ma chyba cos zrobić z Django's 1.1 Proxy Models

1

myślę co szukasz jest admin inlines. W swojej admin.py będziesz chciał dodać coś takiego:

class LocationGroupInline(admin.TabularInline): 
    model = LocationGroup 

class ReportAdmin(admin.ModelAdmin): 
    inlines = [ LocationGroupInline, ] 
admin.site.register(Report, ReportAdmin) 
admin.site.register(LocationGroup) 

Istnieje wiele opcji do włączenia w LocationGroupInline jeśli chcesz dodatkowo skonfigurować wyświetlacz inline powiązanego modelu. Dwa z tych opcji są forma i formset, co pozwoli na korzystanie z niestandardowych klas Django forma i formset dalej dostosowywać wygląd i modelu inline administratora. Za pomocą tego można utworzyć prosty formularz, który wyświetla tylko żądane pole wyboru wielokrotnego wyboru (z wyjątkiem pola M2M nie będzie możliwe wyświetlanie jako pojedyncze menu rozwijane, ale pole wielokrotnego wyboru). Na przykład:

class MyLocationGroupForm(forms.Form): 
    location = forms.MultipleModelChoiceField(
      queryset=LocationGroup.objects.all()) 

class LocationGroupInline(admin.TabularInline): 
    model = LocationGroup 
    form = MyLocationGroupForm 
+1

Zgłoś administracja będzie miała LocationGroups inlined domyślnie pytanie, jak to zrobić na odwrót. Niezależnie od tego spowoduje to wyjątek, że LocationGroup nie ma klucza ForeignKey do ReportAdmin. –