** 2015年11月30日編集:Python 3では、モジュールグローバル__metaclass__
変数はサポートされなくなりました。以下のようAdditionaly、クラスがされた非推奨します:Django 1.10
SubfieldBase
django.db.models.fields.subclassing.SubfieldBase
は非推奨であり、Django 1.10で削除されます。歴史的には、データベースからのロード時に型変換が必要なフィールドを処理するために使用されていましたが、.values()
呼び出しや集計では使用されていませんでした。に置き換えられましたfrom_db_value()
。
新しいアプローチでto_python()
は、の場合のように、割り当て時にメソッドが呼び出されないことに注意してくださいSubfieldBase
。
したがって、from_db_value()
ドキュメントとこの例で示唆されているように、このソリューションは次のように変更する必要があります。
class CharNullField(models.CharField):
"""
Subclass of the CharField that allows empty strings to be stored as NULL.
"""
description = "CharField that stores NULL but returns ''."
def from_db_value(self, value, expression, connection, contex):
"""
Gets value right out of the db and changes it if its ``None``.
"""
if value is None:
return ''
else:
return value
def to_python(self, value):
"""
Gets value right out of the db or an instance, and changes it if its ``None``.
"""
if isinstance(value, models.CharField):
# If an instance, just return the instance.
return value
if value is None:
# If db has NULL, convert it to ''.
return ''
# Otherwise, just return the value.
return value
def get_prep_value(self, value):
"""
Catches value right before sending to db.
"""
if value == '':
# If Django tries to save an empty string, send the db None (NULL).
return None
else:
# Otherwise, just pass the value.
return value
adminでcleaned_dataをオーバーライドするよりも良い方法は、charfieldをサブクラス化することだと思います。この方法は、フィールドにアクセスするフォームに関係なく、「そのまま機能する」でしょう。''
データベースに送信される直前をキャッチし、データベースから送信された直後にNULLをキャッチすることができます。それ以外のDjangoは知りません/気にしません。簡単で汚い例:
from django.db import models
class CharNullField(models.CharField): # subclass the CharField
description = "CharField that stores NULL but returns ''"
__metaclass__ = models.SubfieldBase # this ensures to_python will be called
def to_python(self, value):
# this is the value right out of the db, or an instance
# if an instance, just return the instance
if isinstance(value, models.CharField):
return value
if value is None: # if the db has a NULL (None in Python)
return '' # convert it into an empty string
else:
return value # otherwise, just return the value
def get_prep_value(self, value): # catches value right before sending to db
if value == '':
# if Django tries to save an empty string, send the db None (NULL)
return None
else:
# otherwise, just pass the value
return value
私のプロジェクトでは、これをextras.py
自分のサイトのルートにあるファイルにダンプしました。その後from mysite.extras import CharNullField
、アプリのmodels.py
ファイルだけに入れることができます。フィールドはCharFieldと同じように機能します。フィールドをblank=True, null=True
宣言するときに設定することを忘れないでください。そうしないと、Djangoが検証エラー(フィールドが必要)をスローするか、NULLを受け入れないdb列を作成します。
def get_db_prep_value(self, value, connection, prepared=False)
、メソッド呼び出しとして必要になります。チェックgroups.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJをより情報のため。次のメソッドも私にとっては機能します:def get_prep_value(self、value):if value == "":#if Django試行s to '' string、send the db None(NULL)return None else:return value #otherwise、just値を渡す