【发布时间】:2011-06-17 20:19:42
【问题描述】:
假设我有一个描述办公室打印机的模型。他们可能准备好工作或不准备工作(可能在存储区或已购买但尚未在办公室......)。该模型必须有一个表示打印机实际位置的字段(“秘书办公室”、“接待处”……)。不能有两个重复的位置,如果它不工作,它就不应该有一个位置。
我想要一个列表,其中显示所有打印机,并且每个打印机都有它所在的位置(如果有的话)。像这样的:
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 的最佳方式吗?
谢谢,
【问题讨论】:
标签: django-models unique