Django unique_together 不适用于ForeignKey=None
我看到一些人在我之前遇到了这个问题,但是在旧版本的 Django 上,我运行在 1.2.1 上。
我有一个如下所示的模型:
class Category(models.Model):
objects = CategoryManager()
name = models.CharField(max_length=30, blank=False, null=False)
parent = models.ForeignKey('self', null=True, blank=True, help_text=_('The direct parent category.'))
class Meta:
unique_together = ('name', 'parent')
每当我尝试在管理中保存一个父级设置为“无”的类别时,当存在另一个具有相同名称且父级设置为“无”的类别时,它仍然有效。
关于如何优雅地解决这个问题的想法?
I saw some ppl had this problem before me, but on older versions of Django, and I'm running on 1.2.1.
I have a model that looks like:
class Category(models.Model):
objects = CategoryManager()
name = models.CharField(max_length=30, blank=False, null=False)
parent = models.ForeignKey('self', null=True, blank=True, help_text=_('The direct parent category.'))
class Meta:
unique_together = ('name', 'parent')
Whenever i try to save in the admin a category with a parent set to None, it still works when there's another category with the SAME name and parent set to None.
Ideas on how to solve this gracefully?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
唯一的共同约束是在数据库级别强制执行的,并且您的数据库引擎似乎没有对空值应用该约束。
在 Django 1.2 中,您可以定义 clean 方法 为您的模型提供自定义验证。就您而言,您需要在父级为“无”时检查具有相同名称的其他类别的东西。
如果您通过 Django 管理编辑类别,将自动调用 clean 方法。在您自己看来,您必须调用
category.fullclean()
。The unique together constraint is enforced at the database level, and it appears that your database engine does not apply the constraint for null values.
In Django 1.2, you can define a clean method for your model to provide custom validation. In your case, you need something that checks for other categories with the same name whenever the parent is None.
If you are editing categories through the Django admin, the clean method will be called automatically. In your own views, you must call
category.fullclean()
.我也遇到了这个问题,并通过使用
clean
方法创建一个超级模型(如 Alasdair 建议的)并使用它作为我所有模型的基类来解决它:I had that problem too and solved it by creating a supermodel with
clean
method (like Alasdair suggested) and use it as base class for all my models:不幸的是,对于我们这些使用 PostgreSQL 作为后端数据库引擎的人来说,这个问题永远不会有解决方案:
“目前,只有 B 树索引可以声明为唯一。
当索引声明为唯一时,不允许具有相等索引值的多个表行被视为相等。多列唯一索引只会拒绝多行中所有索引列都相等的情况
。是为表定义的。索引涵盖构成主键或唯一约束(多列索引,如果适用)的列,并且是强制执行约束的机制。”
来源: https://www.postgresql.org /docs/9.0/indexes-unique.html
Unfortunately, for those of us using PostgreSQL as our backend database engine, there will never have a fix for this issue:
"Currently, only B-tree indexes can be declared unique.
When an index is declared unique, multiple table rows with equal indexed values are not allowed. Null values are not considered equal. A multicolumn unique index will only reject cases where all indexed columns are equal in multiple rows.
PostgreSQL automatically creates a unique index when a unique constraint or primary key is defined for a table. The index covers the columns that make up the primary key or unique constraint (a multicolumn index, if appropriate), and is the mechanism that enforces the constraint."
Source: https://www.postgresql.org/docs/9.0/indexes-unique.html