Django:如何制作一个独特的空白模型.CharField?

Django: How to make an unique, blank models.CharField?

假设我有一个模型描述了一个办公室拥有的打印机。他们是否准备好工作(可能在储藏室里,或者已经买了,但还没有到办公室…)。模型必须有一个字段,该字段表示打印机的物理位置("秘书处"、"接待处"、…)。不能有两个重复的位置,如果不工作,则不应该有一个位置。

我想有一个列表,其中显示所有打印机,每个打印机都有其所在的位置(如果有)。像这样:

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

有了这个,我就知道有两台打印机在工作(1和3),还有其他脱机打印机(2和4)。

模型的第一种方法应该是这样的:

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

但这不太管用。您只能在一个空白位置存储一个寄存器。它在数据库中存储为空字符串,并且不允许您多次插入(数据库说该字段还有另一个空字符串)。如果将"null=true"参数添加到此参数中,它的行为也会相同。这是beccuse,而不是在相应的列中插入空值,默认值是空字符串。

在网上搜索,我发现了http://www.maniacmartin.com/2010/12/21/unique-nullable-charfields-django/,它试图以不同的方式解决问题。他说最干净的可能是最后一个,他在其中对charfield类进行了子类化,并重写了一些方法来在数据库中存储不同的值。代码如下:

1
2
3
4
5
6
7
8
9
10
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

这个很好用。您可以在没有位置的情况下存储多个寄存器,因为它存储的不是空字符串,而是空字符串。问题在于它用NOES而不是空字符串来显示空白位置。

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

我假设有一个方法(或多个方法),其中必须指定如何在模型和数据库类管理器之间以两种方式(数据库到模型和模型到数据库)转换数据。

这是获得唯一空白字符域的最佳方法吗?

谢谢,


可以使用模型方法以自定义方式输出值。

像这样(在模型类中):

1
2
3
4
5
6
def location_output(self):
   "Returns location and replaces None values with an empty string"
    if self.location:
        return self.location
    else:
        return""

然后您可以在这样的视图中使用它。

1
2
3
4
5
6
7
8
>>> 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()
''

在你的模板里,像这样。

1
{{ printer.location_output }}

尝试检查这个线程。

允许在Django中为空的唯一字段