Общие много-много отношений в Джанго - PullRequest
2 голосов
/ 07 февраля 2012

Итак, у меня есть 4 сущности, представленные ниже, которые являются сильными и независимыми сущностями в моем приложении, теперь проблема в том, что каждая статья или картинка могут быть «помечены» с предъявителем или событием, поскольку они являются 4 изэти независимые объекты, которые могут стать более сложными. Неправильно добавлять поля Event и Presenter в Article и Picture или наоборот, особенно потому, что они могут быть помечены как none.
В долгосрочной перспективе другие объекты также могутдолжны быть помечены, и могут появиться другие помечаемые объекты.

class Article(models.Model):
    #Fields
class Picture(models.Model):
    #Fields
class Presenter(models.Model):
    # Fields
class Event(models.Model):
    # Fields

Чем ближе я подхожу к некоторой промежуточной модели на основе двунаправленного типа содержимого, подобной этой (еще не тестировал, поскольку этонемного сложнее, чем это), но я ищу идеи:

class GenericTag(models.Model):
    # Event,Presenter instance..
    tagcontent_type = models.ForeignKey(ContentType)
    tagobject_id = models.PositiveIntegerField()
    tagcontent_object = generic.GenericForeignKey('tagcontent_type', 'tagobject_id')
    # Picture,Article instance
    objcontent_type = models.ForeignKey(ContentType)
    objobject_id = models.PositiveIntegerField()
    objcontent_object = generic.GenericForeignKey('objcontent_type', 'objobject_id')

И с этим просто делать запросы на основе информации, которую я имею, я думаю, что должны быть более элегантные способы сделать это без набивкивсе теговые модели как поля в теговые модели.

1 Ответ

2 голосов
/ 07 февраля 2012

Другой подход без общих внешних ключей заключается в использовании наследования модели:

class Tag(models.Model):
    pass
class Taggable(models.Model):
    pass

class Article(Taggable):
    # Fields
class Picture(Taggable):
    # Fields
class Presenter(Tag):
    # Fields
class Event(Tag):
    # Fields

class TagInstance(models.Model):
    tagged = models.ForeignKey(Taggable)
    tag = models.ForeignKey(Tag)

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

...