Wes*_*Dec 22 python sql django
我有一个看起来像这样的Django模型:
class MyModel(models.Model):
parent = models.ForeignKey(ParentModel)
name = models.CharField(blank=True, max_length=200)
... other fields ...
class Meta:
unique_together = ("name", "parent")
Run Code Online (Sandbox Code Playgroud)
这按预期工作; 如果同时存在name
多次,parent
则会出现错误:"具有此Name和Parent的MyModel已存在."
但是,当我保存多个MyModel
相同parent
但name
字段为空白时,我也会收到错误,但是应该允许这样做.所以基本上我不想在name
字段为空时得到上述错误.这有可能吗?
rom*_*rcz 16
首先,空白(空字符串)与null('' != None
)不同.
其次,当你将字段留空时,通过表单使用的Django CharField将存储空字符串.
因此,如果您的字段不是CharField,那么您应该添加null=True
它.但在这种情况下,你需要做的不仅仅是这些.您需要创建子类forms.CharField
并覆盖它的clean
方法以在空字符串上返回None,如下所示:
class NullCharField(forms.CharField):
def clean(self, value):
value = super(NullCharField, self).clean(value)
if value in forms.fields.EMPTY_VALUES:
return None
return value
Run Code Online (Sandbox Code Playgroud)
然后在ModelForm的表单中使用它:
class MyModelForm(forms.ModelForm):
name = NullCharField(required=False, ...)
Run Code Online (Sandbox Code Playgroud)
这样,如果你把它留空,它将在数据库中存储null而不是空字符串(''
)
Mat*_*ell 11
使用unique_together
,你告诉Django你不希望任何两个MyModel
具有相同parent
和name
属性的实例- 即使name
是一个空字符串也适用.
这是使用unique
相应数据库列上的属性在数据库级别强制执行的.因此,要对此行为进行任何例外处理,您必须避免unique_together
在模型中使用.
相反,您可以通过覆盖save
模型上的方法并在那里强制执行唯一约束来获得您想要的结果.当您尝试保存模型的实例时,您的代码可以检查是否存在具有相同parent
和name
组合的任何现有实例,并且如果存在则拒绝保存实例.但是如果name
是空字符串,您也可以允许保存实例.这个的基本版本可能如下所示:
class MyModel(models.Model):
...
def save(self, *args, **kwargs):
if self.name != '':
conflicting_instance = MyModel.objects.filter(parent=self.parent, \
name=self.name)
if self.id:
# This instance has already been saved. So we need to filter out
# this instance from our results.
conflicting_instance = conflicting_instance.exclude(pk=self.id)
if conflicting_instance.exists():
raise Exception('MyModel with this name and parent already exists.')
super(MyModel, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
希望有所帮助.