Как добавить двунаправленные многоточие в 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()

Ответ 1

Обходной путь, который я нашел, заключался в том, чтобы следовать инструкциям 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,

Ответ 2

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

Отказ от ответственности: это всего лишь приблизительная идея

Изменить: возможно, что-то связано с Django 1.1 Proxy Models

Ответ 3

Я думаю, что вы ищете, 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