Абстрактные модели и иностранные ключи в Django - PullRequest
11 голосов
/ 23 сентября 2011

Я работаю над проектом django, в котором я создаю набор из трех абстрактных моделей, которые позже я буду использовать для различных приложений.Проблема, с которой я сталкиваюсь, заключается в том, что я хочу подключить эти модели через ForeignKey, но django говорит мне, что он не может назначать иностранные ключи абстрактной модели.

Мое текущее решение состоит в том, чтобы назначать иностранные ключи при создании экземпляра классав других моих приложениях.Тем не менее, я пишу менеджер для абстрактных классов (книги и страницы) прямо сейчас, и мне нужно было бы получить доступ к этим иностранным ключам.То, что я в основном пытаюсь сделать, - это получить количество слов в книге без сохранения состояния, следовательно, без сохранения ее в поле страницы или книги.

Модель выглядит примерно так:

class Book(models.Models):
    name = models.CharField(...)
    author = models.CharField(...)
    ...

    class Meta:
        abstract = True

class Page(models.Models):
    book = models.ForeignKey(Book)
    chapter = models.CharField(...)
    ...

    class Meta:
        abstract = True

class Word(models.Models):
    page = models.ForeignKey(Page)
    line = models.IntegerField(...)
    ...

    class Meta:
        abstract = True

Обратите внимание, что эта модель здесь просто для того, чтобы дать пример того, что я пытаюсь сделать, поэтому не нужна ли эта модель (Book-Page-Word) с точки зрения реализации.

Ответы [ 3 ]

13 голосов
/ 24 сентября 2011

Может быть, вам нужен GenericForeignKey, поскольку вы на самом деле не знаете, на какую модель будут указывать ваши ForeignKey? Это означает, что вы потеряете некоторые гарантии «типобезопасности» нормального отношения, но это позволит вам определить эти отношения в более общем виде. Смотри https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.generic.GenericForeignKey

Наследование моделей Django - это классная вещь, и она хороша как ярлык для создания ваших моделей DRYer, но не всегда хорошо сочетается с полиморфными идеями, которые у нас обычно есть о классах.

4 голосов
/ 22 февраля 2013

Как насчет этого подхода?Я собираюсь использовать его самостоятельно, чтобы отложить определение отношений до тех пор, пока я не унаследую.

# Это очень очень надуманный (но простой) пример.

def AbstractBook(AuthorModel):                                                  
    class AbstractBookClass(Model):                                             
        name = CharField(max_length=10)                                         
        author = ForeignKey(AuthorModel)                                        
        class Meta:                                                             
            abstract = True                                                     
    return AbstractBookClass                                                    


class AbstractAuthor(Model):                                                    
    name = CharField(max_length=10)                                             
    class Meta:                                                                 
        abstract = True                                                         


class BadAuthor(AbstractAuthor):                                                
    pass                                                                        

class BadBook(AbstractBook(BadAuthor)):                                         
    pass                                                                        

class GoodAuthor(AbstractAuthor):                                               
    pass                                                                        

class GoodBook(AbstractBook(GoodAuthor)):                                       
    pass                                                                        
0 голосов
/ 22 октября 2014

Две вещи:

1) При создании схемы вам понадобится GenericForeignKey, как уже упоминалось.Но вы должны принять во внимание, что Book with Page имеет отношение многие-ко-многим с Word, тогда как GenericForeignKey просто реализует один-ко-многим .У Django еще нет ничего готового для нормализованной схемы.Что вам нужно будет сделать (если вы заботитесь о нормализации), так это самостоятельно реализовать промежуточное звено (с «сквозным» для конкретных моделей).

2) Если вам нужна обработка языка, используйте реляционную базу данных (сили без ORM Джанго) - не очень эффективный подход, учитывая итоговый размер базы данных и время запроса после нескольких десятков книг.Добавьте к этому дополнительные столбцы, которые вам понадобятся для поиска ваших объединений из-за абстрактных моделей, и это скоро станет очень непрактичным.Я думаю, что было бы более выгодно рассмотреть другие подходы, например, хранить только агрегаты и / или денормализовать (даже рассматривая нереляционные системы хранения в этом случае), основываясь на ваших запросах и представлениях.

...