Django ORM: можно ли связать BooleanField со столбцом char в базе данных? - PullRequest
1 голос
/ 30 декабря 2011

Я «унаследовал» базу данных от нашей старой системы, в которой (среди прочих уродливых вещей) есть столбец в определенной таблице, который должен быть логическим, вместо этого это varchar (1) с «N» или «0 'для представления false и' Y 'или' 1 'для представления true (различные части кода используют одно или другое соглашение при записи, но, очевидно, все они могут распознавать оба при чтении).

Я портирую / переписываю систему, изначально написанную на Java, на Python + Django, и я смогу закрыть старый и «почистить» беспорядок в базе данных только после завершения порта.

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

Ответы [ 2 ]

5 голосов
/ 31 декабря 2011

Вы можете создать свой собственный класс поля, который будет действовать так, как вы хотите, создав подкласс django.db.models.Field и реализовав метод to_python , например

from django.db import models

class MyField(models.CharField):

     def to_python(self, value):
         if value in ('Y', '1'):
             return True
         if value in ('N', '0'):
             return False
         raise ValueError

Надеюсь, что это даст вам некоторое представление:)

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

Моя ситуация похожа, но устаревшие данные последовательно используют Y и N для представления True и False, но у меня есть проблема с добавлением некоторых полей, допускающих Null.Итак, вот мои пользовательские типы полей.Я думаю, что это немного более полные примеры того, что вы можете сделать в этой ситуации, и я также унаследовал от типов BooleanField, которые, я думаю, лучше подходят для отображения / редактирования этих полей в формах.

from django.db import models

class YNBooleanField(models.BooleanField):

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 1
        super(YNBooleanField, self).__init__(*args, **kwargs)

        def to_python(self, value):
        if value in ('Y', 'y'):
            return True
        elif value in ('N', 'n'):
            return False
        else:
            raise ValueError

    def get_prep_value(self, value):
        if value:
            return 'Y'
        else:
            return 'N'

class NullYNBooleanField(models.NullBooleanField):

        def __init__(self, *args, **kwargs):
            kwargs['max_length'] = 1
            super(NullYNBooleanField, self).__init__(*args, **kwargs)

        def to_python(self, value):
            if value is None:
            return None
        elif value in ('Y', 'y'):
            return True
        elif value in ('N', 'n'):
            return False
        else:
            raise ValueError

    def get_prep_value(self, value):
        if value is None:
            return None
        elif value:
            return 'Y'
        else:
            return 'N'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...