Django - 确保同一模型类型的 table 中的 2 个字段对实体没有相同的值
Django - Ensure 2 fields in a table of the same model type don't have the same value for an entity
所以我有一个用户 class 并且一个用户可以关注另一个用户,但我不希望用户能够关注他们自己。有没有办法将此约束添加到 Django?
class FollowUser(AbstractSimpleModel):
follower_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower_id')
followee_id = models.OneToOneField(User, on_delete=models.CASCADE, related_name='followee_id')
由于您需要根据其他字段的值来验证该字段的值,这里是 FollowUser.follower_id
和 FollowUser.followee_id
,您可以遵循 Django 如何处理 validation of fields 的过程:
在您要运行验证的地方实施Model.clean()
覆盖 Model.save() 以通过 Model.full_clean()
调用完整的验证过程。需要这个明确的步骤,因为如文件所示:
Note that full_clean() will not be called automatically when you call
your model’s save() method. You’ll need to call it manually when you
want to run one-step model validation for your own manually created
models. For example:
from django.core.exceptions import ValidationError
from django.db import models
class UserDummy(models.Model):
pass
class FollowUser(models.Model):
follower_id = models.ForeignKey(UserDummy, on_delete=models.CASCADE, related_name='follower_id')
followee_id = models.OneToOneField(UserDummy, on_delete=models.CASCADE, related_name='followee_id')
def clean(self):
if self.follower_id == self.followee_id:
raise ValidationError("Users can't follow themselves")
def save(self, *args, **kwargs):
self.full_clean()
super().save(*args, **kwargs)
样本运行
设置数据:
>>> from my_app.models import *
>>> UserDummy.objects.values()
<QuerySet [{'id': 1}, {'id': 2}, {'id': 3}]>
>>> user1 = UserDummy.objects.get(id=1)
>>> user2 = UserDummy.objects.get(id=2)
>>> user3 = UserDummy.objects.get(id=3)
验证失败:
>>> # Using Model.save()
>>> FollowUser(follower_id=user1, followee_id=user1).save()
Traceback (most recent call last):
raise ValidationError(errors)
django.core.exceptions.ValidationError: {'__all__': ["Users can't follow themselves"]}
>>>
>>> # Using Model.objects.create()
>>> FollowUser.objects.create(follower_id=user1, followee_id=user1)
Traceback (most recent call last):
raise ValidationError(errors)
django.core.exceptions.ValidationError: {'__all__': ["Users can't follow themselves"]}
验证成功:
>>> # Using Model.save()
>>> FollowUser(follower_id=user1, followee_id=user2).save()
>>>
>>> # Using Model.objects.create()
>>> FollowUser.objects.create(follower_id=user2, followee_id=user3)
<FollowUser: FollowUser object (2)>
>>>
>>> FollowUser.objects.values()
<QuerySet [{'id': 1, 'follower_id_id': 1, 'followee_id_id': 2}, {'id': 2, 'follower_id_id': 2, 'followee_id_id': 3}]>
注意:请注意,如果您使用 Model.objects.bulk_create(),您将需要进一步更改,因为它不会调用记录的 Model.save()
功能:
bulk_create()
The model’s save() method will not be called, and the pre_save and
post_save signals will not be sent.
所以我有一个用户 class 并且一个用户可以关注另一个用户,但我不希望用户能够关注他们自己。有没有办法将此约束添加到 Django?
class FollowUser(AbstractSimpleModel):
follower_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower_id')
followee_id = models.OneToOneField(User, on_delete=models.CASCADE, related_name='followee_id')
由于您需要根据其他字段的值来验证该字段的值,这里是 FollowUser.follower_id
和 FollowUser.followee_id
,您可以遵循 Django 如何处理 validation of fields 的过程:
在您要运行验证的地方实施Model.clean()
覆盖 Model.save() 以通过
Model.full_clean()
调用完整的验证过程。需要这个明确的步骤,因为如文件所示:Note that full_clean() will not be called automatically when you call your model’s save() method. You’ll need to call it manually when you want to run one-step model validation for your own manually created models. For example:
from django.core.exceptions import ValidationError
from django.db import models
class UserDummy(models.Model):
pass
class FollowUser(models.Model):
follower_id = models.ForeignKey(UserDummy, on_delete=models.CASCADE, related_name='follower_id')
followee_id = models.OneToOneField(UserDummy, on_delete=models.CASCADE, related_name='followee_id')
def clean(self):
if self.follower_id == self.followee_id:
raise ValidationError("Users can't follow themselves")
def save(self, *args, **kwargs):
self.full_clean()
super().save(*args, **kwargs)
样本运行
设置数据:
>>> from my_app.models import *
>>> UserDummy.objects.values()
<QuerySet [{'id': 1}, {'id': 2}, {'id': 3}]>
>>> user1 = UserDummy.objects.get(id=1)
>>> user2 = UserDummy.objects.get(id=2)
>>> user3 = UserDummy.objects.get(id=3)
验证失败:
>>> # Using Model.save()
>>> FollowUser(follower_id=user1, followee_id=user1).save()
Traceback (most recent call last):
raise ValidationError(errors)
django.core.exceptions.ValidationError: {'__all__': ["Users can't follow themselves"]}
>>>
>>> # Using Model.objects.create()
>>> FollowUser.objects.create(follower_id=user1, followee_id=user1)
Traceback (most recent call last):
raise ValidationError(errors)
django.core.exceptions.ValidationError: {'__all__': ["Users can't follow themselves"]}
验证成功:
>>> # Using Model.save()
>>> FollowUser(follower_id=user1, followee_id=user2).save()
>>>
>>> # Using Model.objects.create()
>>> FollowUser.objects.create(follower_id=user2, followee_id=user3)
<FollowUser: FollowUser object (2)>
>>>
>>> FollowUser.objects.values()
<QuerySet [{'id': 1, 'follower_id_id': 1, 'followee_id_id': 2}, {'id': 2, 'follower_id_id': 2, 'followee_id_id': 3}]>
注意:请注意,如果您使用 Model.objects.bulk_create(),您将需要进一步更改,因为它不会调用记录的 Model.save()
功能:
bulk_create()
The model’s save() method will not be called, and the pre_save and post_save signals will not be sent.