Джанго GenericForeignKey против набора ForeignKey - PullRequest
0 голосов
/ 05 июля 2019

Я хотел бы обсудить случай использования GenericRelation и GenericForeignKey.

У меня есть 2 модели: Appartement и Mission.И мне нужно создать модель LockCode, которая будет связана с Appartment или Mission.Я добавил GenericForeignKey к LockCode и GenericRelation к Appartement и Mission:

class LockCode(TimeStampedModel):
    context_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    context_id = models.PositiveIntegerField()
    context = GenericForeignKey('context_type', 'context_id')


class Mission(DirtyFieldsMixin, models.Model):
    lock_codes = GenericRelation(
        LockCode,
        content_type_field='context_type',
        object_id_field='context_id',
        related_query_name='mission'
    )

class Appartment(DirtyFieldsMixin, models.Model):
    lock_codes = GenericRelation(
        LockCode,
        content_type_field='context_type',
        object_id_field='context_id',
        related_query_name='appartment'
    )

Все работает нормально.Но добавил уровень сложности, чтобы сравнить с добавлением 2 ForeignKeys, для апартаментов и для миссии.

class LockCode(TimeStampedModel):
  appartement = models.ForeignKey(Appartement, null=True, blank=True)
  mission = models.ForeignKey(Mission, null=True, blank=True)

Так я должен оставить GFK или использовать 2 простых FK?

Ответы [ 2 ]

1 голос
/ 05 июля 2019

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

Если вам никогда не нужно следовать таким отношениям, тогда да, GFK не нужен, и два FK будут лучше.

1 голос
/ 05 июля 2019

Если вы выберете второй вариант, вам нужно будет встроить логику, чтобы убедиться, что либо appartement, либо mission не равно null.Если бы вы когда-либо добавляли больше таких полей внешнего ключа, эта логика становилась бы все более сложной.

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

...