Django模型中可空的TextField或空字符串?

Ant*_*off 8 django database-design

正如我从这个数据库设计问题中所理解的那样,你应该谨慎地使用可空字段,并且每次都要对重新考虑数据设计是否更好进行权衡决策.

但是,让我们说在某些特定情况下,解决方案是允许文本字段包含空值.比如说,有user表和short_bioDjango中由TextField表示的列,并不是必需的.创建一个单独的user_bio表没有意义,对吧?

现在的问题是,空值是空字符串还是空标记?每种选择的利弊是什么?Django如何与数据库一起工作有什么细节可以产生差异?


应该注意的是,django-lint目前报告CharField和TextField实例null=True.

相反,一些开发人员将 '空字符串存储为空白字符串被视为一个坏主意' .

Don*_*Don 17

我认为当'空字符串'意味着'没有值'时,应使用空字符串以避免混合空值和空格意味着相同的事情(例如在搜索或比较中:在某些DBMS中,您无法将NULL与NULL进行比较直接,你必须使用IS NULL运营商).

使用空字符串也会更容易在报告和其他使用'short_bio'的东西中使用它而不通过DOM(例如使用objects.values('short_bio')),而不会在''中转换Null.

此外,Django文档指出:

避免在基于字符串的字段(如CharField和TextField)上使用null,除非您有充分的理由.如果基于字符串的字段具有null = True,则表示它具有"无数据"的两个可能值:NULL和空字符串.在大多数情况下,为"无数据"提供两个可能的值是多余的; Django约定是使用空字符串,而不是NULL.

  • 感谢您的推理和提及我在文档中没有注意到的Django约定. (2认同)

Ant*_*off 5

如果您需要一个应该是唯一但可以允许多个NULL值的可空文本字段,则最好使用NULL而不是空字符串.

Django总是将NULL视为唯一值,同时空字符串总是等于另一个空字符串.请参阅Djangoticket 9039 中允许空值的唯一字段.

要拥有"两全其美",您可以将空值存储为NULL,但通过自定义表单字段显示为空字符串.mightyhal的一个(未经测试的)例子:

from django.db import models


class CharNullField(models.CharField):
    description = "Stores NULL but returns empty string"
    def to_python(self, value):
        # this may be the value right out of the db, or an instance
        if isinstance(value, models.CharField):
            # if an instance, return the instance
            return value
        if value == None:
            # if db has NULL (==None in Python), return empty string
            return ""
        else:
            return value # otherwise, return just the value
    def get_db_prep_value(self, value):
        # catches value right before sending to db
        if value == "":
            # if Django tries to save an empty string, send to db None (NULL)
            return None
        else:
            return value # otherwise, just pass the value
Run Code Online (Sandbox Code Playgroud)