如何防止当前用户使用Django模型约束对自己进行评级



所以我有一个用户模型,每个用户应该能够对其他用户进行评分,但不应该对自己进行评分。

评级模型为

#Rating field in User model
ratings = models.ManyToManyField('self', through='Rating',
symmetrical=False,
related_name='rated_by')
#Rating model
class Rating(models.Model):
rating = models.IntegerField(validators=[validate_rating])
from_user = models.ForeignKey(User, related_name="from_people", on_delete=models.CASCADE)
to_user = models.ForeignKey(User, related_name="to_people", on_delete=models.CASCADE)

有没有一种方法可以使这个功能?我原以为django模型约束会起作用,但我不知道该怎么做。我该如何过滤请求以获取特定用户,以防止他们对自己进行评级?

我试过了:

class Rating(models.Model):
rating = models.IntegerField(validators=[validate_rating])
from_user = models.ForeignKey(User, related_name="from_people", 
on_delete=models.CASCADE)
to_user = models.ForeignKey(User, related_name="to_people", 
on_delete=models.CASCADE)
class Meta:
constraints = [
CheckConstraint(
check = Q(from_user != User, 
to_user != User),
name = 'check_user',
)
]

但我得到了一个Metacheck = Q(from_user != User, NameError: name 'from_user' is not defined作为错误

您可以向模型添加数据库级别的检查约束,以防止Rating模型具有from_user和to_user相同的记录。

from django.db.models import Q, F, CheckConstraint
class Rating(models.Model):
rating = models.IntegerField(validators=[validate_rating])
from_user = models.ForeignKey(User, related_name="from_people", on_delete=models.CASCADE)
to_user = models.ForeignKey(User, related_name="to_people", on_delete=models.CASCADE)
class Meta:
constraints = [
CheckConstraint(check=~Q(from_user=F('to_user')), name='no_self_rating')
]

Django文档约束引用。

上面添加了数据库级别的约束,但没有进行任何表单验证。

你也可以问

如何过滤请求以获取特定用户以防止他们对自己进行评级?

这里不清楚你的意思。传递给视图函数的请求对象具有一个用户属性,该属性是使用该应用程序的用户。我不确定你的观点是什么样子,但是:

def my_view(request):
request.user  # This is the user making the action
... # Other view code
return HttpResponse(...)

您可以将request.user传递到表单,并验证用户没有对自己进行评级。

一个负的CheckConstraint应该可以满足您的需要。

from django.db import models

class Rating(models.Model):
rating = models.IntegerField(validators=[validate_rating])
from_user = models.ForeignKey(User, related_name="from_people", on_delete=models.CASCADE)
to_user = models.ForeignKey(User, related_name="to_people", on_delete=models.CASCADE)
class Meta:
constraints = [
models.CheckConstraint(
check=~models.Q(from_user=models.F('to_user')),
name='users_cannot_rate_themselves'
),
]

最新更新