Разработка базы данных Django: ManyToManyField при использовании Inlines - PullRequest
3 голосов
/ 17 января 2012

Я пытаюсь спроектировать свою первую базу данных и немного застрял.Дизайн выглядит следующим образом: у вас есть автор, который может иметь много книг.Каждая книга может иметь много страниц.На каждой странице может быть много картинок.Каждая страница уникальна (ForeignKey).Изображения могут быть не уникальными (вы можете использовать одно и то же изображение на разных страницах / в книгах, поэтому это должно быть ManyToMany). Моя проблема в том, что я не могу получить изображения ManyToManyField при использовании Inlines.

Если я изменю ForeignKey на ManyToMany, я получу исключение "<class 'books.models.Picture'> has no ForeignKey to <class 'books.models.Page'>».Я посмотрел здесь и здесь , но понятия не имею, как применить это в моем случае.

Вот так выглядит мой models.py:

class Author(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=50)

class Page(models.Model):
    book = models.ForeignKey(Book)
    contents = models.TextField(max_length=15999)

class Picture(models.Model):
    page = models.ForeignKey(Page) # ideally, this should be many-to-many
    picture_uuid = models.CharField(max_length=36)

В моем интерфейсе администратора я хотел бы, чтобы все книги, которые автор написал на странице автора.Кроме того, я хотел бы, чтобы все страницы книги были на странице книг и так далее.Поэтому мой admin.py выглядит так:

class PictureAdmin(admin.ModelAdmin):
    list_display = ('id', 'picture_uuid')

class PictureInline(admin.TabularInline):
    model = Picture

class PageAdmin(admin.ModelAdmin):
    list_display = ('id', 'page_uuid')

    inlines = [
        PictureInline,
        ]

class PageInline(admin.TabularInline):
    model = Page

class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'title')

    inlines = [
        PageInline,
        ]

class BookInline(admin.TabularInline):
    model = Book

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'email')

    inlines = [
        BookInline,
        ]

Ответы [ 2 ]

3 голосов
/ 17 января 2012

Вы не можете использовать ManyToManyFields напрямую как встроенные. Inlines должен иметь внешний ключ обратно к редактируемой модели, и, конечно же, фактический потомок не имеет. Если вы хотите отредактировать встроенный файл M2M, лучше всего использовать таблицу through, поэтому вам нужно изменить InlineModelAdmin следующим образом:

class PictureInline(admin.TabularInline):
    model = Page.pictures.through

Что требует, чтобы ManyToManyField был на модели Page:

class Page(models.Model):
    ...
    pictures = models.ManyToManyField(Picture)
0 голосов
/ 17 января 2012

В соответствии с документацией в https://docs.djangoproject.com/en/dev/ref/contrib/admin/#working-with-many-to-many-models вы должны определить атрибут model во встроенном

...