Что я должен сделать, чтобы изменить Django ForeignKey, который изначально требовался сделать его необязательным сейчас? - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть модель данных со многими полями ForeignKey. Из первоначального дизайна некоторые являются необязательными (через blank=True, null=True), в то время как другие требуются (полагаясь на значения по умолчанию blank=False, null=False).

Теперь, спустя несколько лет, я хочу изменить некоторые из них, чтобы они были необязательными. Я добавляю blank=True, null=True к этим полям в модели данных, запускаю manage makemigrations и manage migrate, но страница администратора ведет себя точно так же, как и раньше: те, которые когда-то требовались, все еще требуются.

EDIT: С тех пор я узнал, что я могу переопределить AdminForm __init__, как показано ниже, чтобы решить проблему. Я пробовал это раньше, основываясь на Сделать ForeignKey необязательным в Django Admin? , но у меня это не сработало; теперь это так, я, должно быть, обманываю в своем тестировании. Мне все еще очень любопытно, почему это переопределение необходимо, хотя для FK, которые не были необязательными с момента их создания.

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['SOME_FIELD_NAME'].required = False

РЕДАКТИРОВАТЬ # 2: Подозревая, что мои проблемы могут возникнуть из-за FK на модели, которая является базовым классом для двух подклассов, я подумал, что должен поэкспериментировать с более простым FK и угадайте, что? У меня не было проблем там. Поэтому, чтобы сделать это немного более конкретным для читателя здесь, я реализовал интерфейс Django для iptables и, таким образом, имею здесь следующие модели данных:

class Protocol(models.Model):
    """
    A IP transmission protocol.
    """
    # details unimportant


class NetworkLocation(models.Model):
    """
    An abstract network location: a host or subnet.
    """
    # details unimportant


class Host(NetworkLocation):
    """
    A host name or its IP address.
    """
    # details unimportant


class Subnet(NetworkLocation):
    """
    A network IP address with /mask.
    """
    # details unimportant


class Rule(models.Model):
    """
    An iptables rule.
    """
    # only pertinent details shown here
    protocol = models.ForeignKey(Protocol, on_delete=models.CASCADE)
    src = models.ForeignKey(
        NetworkLocation, verbose_name='source',
        blank=True, null=True, related_name='+', on_delete=models.CASCADE,
    )
    dst = models.ForeignKey(
        NetworkLocation, verbose_name='destination',
        blank=True, null=True, related_name='+', on_delete=models.CASCADE,
    )

Итак, исходя из вышеизложенного, мои проблемы были с Rule. Как указано, protocol, src и dst все были обязательны. Теперь я хотел сделать src и dst необязательно, и, следовательно, это так вопрос. Я только что узнал, что я мог сделать protocol необязательно, просто добавив blank=True, null=True, но для src и dst кажется необходимым иметь __init__ моего RuleAdminForm расширено, как показано выше. Почему это необходимо для src и dst, но не protocol?

...