2009-08-27 9 views
11

Dans mon models.py j'ai quelque chose comme:Comment ajouter manytomanyfields bi-directionnel dans l'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) 

Lorsque je rentre dans la page d'administration pour le rapport, il montre un beau champ de choix multiples. Comment puis-je ajouter le même champ de choix multiple dans LocationGroup? Je peux accéder à tous les rapports en appelant LocationGroup.report_set.all()

+0

billets connexes: https://code.djangoproject.com/ticket/897 – guettli

Répondre

8

La solution que j'ai trouvé de suivre les instructions pour ManyToManyFields with intermediary models. Même si vous n'utilisez pas la fonction "through", faites comme si vous étiez et créez un modèle stub avec le ForeignKey nécessaire.

# 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

Considéré comme l'implémentation la plus facile, thx! –

+0

Le plus facile, mais toujours un hack. Je souhaite que Django puisse supporter cela d'une manière plus élégante. –

2

Je pense que yon peut combiner cet exemple de code (source) pauses 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) 

avec this snippet

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

obtenir quelque chose comme

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) 

Avertissement: ceci est juste une idée approximative

Edit: Il est probablement someting à voir avec Django's 1.1 Proxy Models

1

Je pense que ce que vous recherchez est admin inlines. Dans votre admin.py vous voulez ajouter quelque chose comme ceci:

class LocationGroupInline(admin.TabularInline): 
    model = LocationGroup 

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

Il y a beaucoup d'options à inclure dans LocationGroupInline si vous souhaitez configurer la possibilité d'affichage en ligne du modèle connexe. Deux de ces options sont formulaire et formset, qui vous permet d'utiliser des classes Django Form et FormSet personnalisées pour personnaliser davantage l'apparence de l'administrateur de modèle en ligne. En utilisant ceci, vous pouvez créer un formulaire simple qui affiche uniquement le champ à choix multiples souhaité (à l'exception d'un champ M2M, il ne sera pas possible de l'afficher sous la forme d'une seule liste déroulante, mais d'une boîte de sélection multiple). Par exemple:

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

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

admin rapport aura LocationGroups inline par défaut, la question était de savoir comment faire l'inverse. Quoi qu'il en soit, cela déclenchera une exception que LocationGroup n'a pas ForeignKey à ReportAdmin. –

Questions connexes