jav*_*ved -1 django django-models
class Category(models.Model):
name = models.CharField(max_length=200)
parent = models.ForeignKey("self",
blank=True,
null=True,
related_name='children',
on_delete=models.CASCADE)
class Meta:
unique_together = [
('parent', 'name'),
]
Run Code Online (Sandbox Code Playgroud)
在这个模型中,我可以使用以下命令创建多个对象
Category.objects.create(name="cat1", parent=None) #
Category.objects.create(name="cat1", parent=None)
# unique_together constraint should not
# allow this second object's reaction, but it is;
# behavior is the same even when the parent is not None.
Run Code Online (Sandbox Code Playgroud)
我使用的 Django 版本是3.0.8
Postgres 12.3 psycopg2-binary 2.8.5
更新:
Category.objects.create(name="cat1", parent=obj) #
Category.objects.create(name="cat1", parent=obj)
Run Code Online (Sandbox Code Playgroud)
即使父对象不是“无”,也会创建第二个对象或记录。
In [2]: Category2.objects.create(name="cat1")
Out[2]: <Category2: cat1>
In [3]: Category2.objects.create(name="cat1")
Out[3]: <Category2: cat1>
In [4]: par1 = Category2.objects.create(name="cat1")
In [6]: par1 = Category2.objects.create(name="cat2", parent=par1)
In [7]: par2 = Category2.objects.create(name="cat2", parent=par1)
Run Code Online (Sandbox Code Playgroud)
这个问题不是重复的,它与问题中解释的可空外键无关。
数据库在检查唯一性时将忽略 NULL,这意味着两个NULLs 不被视为分支唯一性。
您可以利用约束框架有条件地检查唯一性:
from django.db.models import Q, UniqueConstraint
class Category(models.Model):
name = models.CharField(max_length=200)
parent = models.ForeignKey(
'self',
blank=True,
null=True,
related_name='children',
on_delete=models.CASCADE
)
class Meta:
constraints = [
UniqueConstraint(
fields=['name', 'parent'], name='name_unique'
),
UniqueConstraint(
fields=['name'], condition=Q(parent=None), name='name_unique2'
)
]Run Code Online (Sandbox Code Playgroud)
这里如果parent是这样NULL,我们检查 的唯一性name。然而,某些数据库可能不会强制执行此类检查。
显然,在 Microsoft 的 SQL Server 上,情况并非如此,正如@Melvyn所说。在这种情况下,这将是想要的行为。但以我的拙见,这通常是不受欢迎的行为。NULL通常正是用于此目的。
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |