Комбинация внешних ключей и предопределенных значений как выбор для поля модели Django - PullRequest
1 голос
/ 15 октября 2019
Поле

A ForeignKey в одной из моделей хранит ссылку на другую модель, в которой хранятся различные версии документов terms and conditions.

class Venue(models.Model):
    tc = models.ForeignKey(
    'my_app.TC',
    on_delete=models.CASCADE,
    help_text=_('Version of tc used by this venue')
)

Таким образом, каждый Venue может выбрать одну из версий tc, что соответствует их потребностям.

Записи в таблице TC часто добавляются, поэтому, если для Venue требуется использовать последнюю версию документа, кто-то должен вручную обновить ее с помощью django admin. Это плохо продуманное решение, поскольку в базе данных есть десятки Venue записей, и все они имеют разные подходы к использованию tc:

  • В некоторых местах требуется автоматическое обновление tc допоследняя версия
  • Некоторые хотят / должны увеличить свою tc версию вручную
  • В некоторых заведениях tc вообще не используется

Для достижения цели необходимо иметь 2 дополнительных параметра по умолчанию для каждого Venue:

1. ---- (blank: venue does not use any `tc`)
2. Latest (venue automatically uses latest version of `tc` available`

и неопределенное количество доступных параметров tc (например, внешние ключи для модели TC)

1. v1.0.0
2. v2.1.0
3. ...

В этом случае Latest не является отношением к TC объекту. Таким образом, список вариантов для поля tc в django admin может выглядеть примерно так:

- ---- (blank)
- Latest (literally option is named this was, not latest added `tc` object`)
- v1.0.0
- v2.1.0
- ... (other `tc` objects follow down the list)

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

Существует ли способ предоставления значений по умолчанию для поля ForeignKey ИЛИ с использованием внешних ключей в качестве параметров в choices для CharField?

1 Ответ

1 голос
/ 15 октября 2019

Вы можете попытаться создать настраиваемое поле, но я думаю, что это будет слишком хлопотно. Лучший способ сделать это - создать два поля, ForeignKey и простой флаг, который определяет, будет ли получен последний tc или нет. Затем вы можете определить пользовательское свойство, чтобы получить правильный TC.

Чтобы разрешить пустые поля ForeignKey, просто установите для null и blank значение True.

Примерно так:

class Venue(models.Model):

     _tc = models.ForeignKey(
          'my_app.TC',
          on_delete=models.CASCADE,
          help_text=_('Version of tc used by this venue'),
          null = True, blank = True
      )

     use_latest_tc = models.BooleanField(default=False)

     @property
     def tc(self):
         if self.use_latest_tc:
              return TC.objects.latest()
         return self._tc

В зависимости от того, где вы измените это значениеВы можете написать собственный JS для своей формы, который скрывает ForeignKeyField, когда включено использование last.

Следующее не проверено, но, возможно, сработает. Также, создав сеттер для tc, вы можете создать форму с полем 'tc' и возможными значениями:

@tc.setter
def tc(self, value):
    if value == 'latest':
        self.use_latest_tc = True
        self._tc = True
    else:
        self.use_latest_tc = False
        self._tc = value
...