Джанго: Как сделать уникальные, пустые модели. CharField? - PullRequest
4 голосов
/ 29 января 2011

Представьте, что у меня есть модель, описывающая принтеры, которые есть в офисе.Они могут быть готовы к работе или нет (может быть, в хранилище или оно было куплено, но еще не в офисе ...).Модель должна иметь поле, которое представляет физическое местоположение принтера («Офис секретаря», «Приемная», ...).Не может быть двух повторных местоположений, и если оно не работает, оно не должно иметь местоположения.

Я хочу иметь список, в котором отображаются все принтеры, и для каждого из них должны быть местоположения, в которых он находится (если онесть).Примерно так:

ID | Location
1  | "Secretary's office"
2  |
3  | "Reception"
4  | 

С этим я могу узнать, что работают два принтера (1 и 3), а другие автономно (2 и 4).

ПервыйПодход к модели должен быть примерно таким:

class Printer(models.Model):
      brand = models.CharField( ...
      ...
      location = models.CharField( max_length=100, unique=True, blank=True )

Но это не работает должным образом.Вы можете хранить только один регистр с одним пустым местоположением.Он хранится как пустая строка в базе данных и не позволяет вставлять более одного раза (база данных говорит, что для этого поля есть другая пустая строка).Если вы добавите к этому параметр «null = True», он будет вести себя так же.Это потому, что вместо вставки значения NULL в соответствующий столбец значением по умолчанию является пустая строка.

При поиске в Интернете я обнаружил http://www.maniacmartin.com/2010/12/21/unique-nullable-charfields-django/,, который пытается решить проблему различными способами.,Он говорит, что, вероятно, самый чистый - последний, в котором он наследует класс CharField и переопределяет некоторые методы для хранения различных значений в базе данных.Вот код:

from django.db import models
class NullableCharField(models.CharField):
     description = "CharField that obeys null=True"
     def to_python(self, value):
         if isinstance(value, models.CharField):
             return value
         return value or ""

     def get_db_prep_value(self, value):
         return value or None

Это отлично работает.Вы можете хранить несколько регистров без указания местоположения, потому что вместо вставки пустой строки он хранит NULL.Проблема в том, что он показывает пустые места с Nones вместо пустой строки.

ID | Location
1  | "Secretary's office"
2  | None
3  | "Reception"
4  | None

Я предположил, что существует метод (или несколько), в котором необходимо указать способ преобразования данных между моделью и менеджером классов базы данных двумя способами (от базы данных к модели и модели).в базу данных).

Это лучший способ иметь уникальный пустой CharField?

Спасибо,

Ответы [ 2 ]

1 голос
/ 30 января 2011

Вы можете использовать метод модели для вывода значений пользовательским способом.

Примерно так (в классе вашей модели):

def location_output(self):
    "Returns location and replaces None values with an empty string"
    if self.location:
        return self.location
    else:
        return ""

Затем вы можете использовать его в представлениях, таких какthis.

>>> Printer.objects.create(location="Location 1")
<Printer: Printer object>
>>> Printer.objects.create(location=None)
<Printer: Printer object>
>>> Printer.objects.get(id=1).location_output()
u'Location 1'
>>> Printer.objects.get(id=2).location_output()
''

А в ваших шаблонах вот так.

{{ printer.location_output }}
1 голос
/ 29 января 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...