Как добавить двунаправленные manytomanyfields в Django admin?

в моем models.py у меня есть что-то вроде:

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 (стандарт):

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

когда я вхожу на страницу администратора для отчета, он показывает хорошее поле множественного выбора. Как добавить одно и то же поле множественного выбора в LocationGroup? Я могу открыть все отчеты по телефону LocationGroup.report_set.all ()

3 ответов


обходной путь, который я нашел, состоял в том, чтобы следовать инструкциям для ManyToManyFields с промежуточными моделями. Даже если вы не используете функцию "сквозной" модели, просто притворитесь, что это так, и создайте модель заглушки с необходимым ForeignKey.

# 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,

Я думаю, что вы можете объединить этот пример кода (источник), который нарушает 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)

С этот фрагмент

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

получить что-то вроде

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)

отказ от ответственности: это просто грубая идея

Edit: вероятно, есть что-то делать с 1.1 прокси-модели Django


Я думаю, что вы ищете admin inlines. В твоем admin.py вы захотите добавить что-то вроде этого:

class LocationGroupInline(admin.TabularInline):
    model = LocationGroup

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

есть много вариантов для включения в LocationGroupInline, если вы хотите дополнительно настроить встроенное отображение связанной модели. Два из этих вариантов являются форма и formset, что позволит вам использовать пользовательские классы Django Form и FormSet для дальнейшей настройки внешнего вида встроенной модели администратор. Используя это, вы можете создать простую форму, которая отображает только поле множественного выбора, которое вы хотите (за исключением поля M2M, его нельзя будет отобразить как один раскрывающийся список, но несколько полей выбора). Например:

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

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