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中为空的唯一字段