我正在尝试使用 UniqueConstraint,但在尝试按照我想要的方式更新它时遇到了一些问题。
我有以下型号
class QueryModel(models.Model):
id = models.AutoField(_("query id"), primary_key=True)
user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
name = models.CharField(_("query name"), max_length=150)
status = models.CharField(
_("query status"),
choices=QueryStatus.choices,
default=QueryStatus.ACTIVE,
)
is_favorite = models.BooleanField(_("favorite"), default=False)
date_created = models.DateTimeField(_("date created"), auto_now_add=True)
class Meta(object):
app_label = "app"
db_table = "query"
constraints = [
models.UniqueConstraint(
fields=("user",),
condition=Q(is_favorite=True),
name="unique_favorite_per_user",
)
]
class QueryView(viewsets.ModelViewSet):
"""
View to list all users in the system.
* Requires token authentication.
* Only admin users are able to access this view.
"""
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
serializer_class = QuerySerializer
aws_client = AWSClient()
def get_queryset(self):
"""
This view should return a list of all the purchases
for the currently authenticated user.
"""
self._paginator = None
return QueryModel.objects.filter(user=self.request.user).order_by("id")
def create(self, request):
serializer = QuerySerializer(
data={
"user": request.user.id,
"name": request.data["name"],
"expiration_date": request.data["expiration_date"],
"json": request.data["json"],
}
)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
def partial_update(self, request, pk=None):
serializer = QuerySerializer(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
if "is_favorite" in serializer.validated_data.keys():
self.get_queryset().update(
is_favorite=ExpressionWrapper(Q(pk=pk), BooleanField())
)
return super().partial_update(request, pk)
router = DefaultRouter(trailing_slash=False)
router.register("auth", AuthView, basename="auth")
router.register("query", QueryView, basename="query")
version_info = json.load(open("./version.json"))
@api_view(["GET"])
def health_check(request):
"""Check if the endpoint is on. Used by container orchestration system."""
return Response({"status": "pass", **version_info})
urlpatterns = [
path("", health_check),
*router.urls,
]
因此,在我的系统中,用户可以创建查询并将其设置为收藏夹,但每个用户只能有 1 个收藏夹查询,因此我创建了 UniqueConstraint 来强制执行该业务规则。
然后我会有一个端点将查询设置为最喜欢的,但是有没有办法让我更新该字段,而不必检查每个用户的所有 is_favorite 字段并手动将它们设置为 False?
我发现this 2年前的StackOverflow帖子提出了一个解决方案,但这个解决方案对我不起作用,我真的很感激一些帮助
如果您想将
QueryModel
与 my_pk
设置为收藏夹主键,请更新:
从 django.db.models 导入 BooleanField、ExpressionWrapper、Q QueryModel.objects.filter(user=my_user).update( is_favorite=ExpressionWrapper(Q(pk=my_pk), BooleanField()) )
如果已有收藏夹,这将自动禁用收藏夹,并将其设置为以
my_pk
作为主键的收藏夹。