unique_together 不防止重复记录

unique_together does not prevent duplicate records

我有两个这样的模型:

class Preference(models.Model):

    lat = models.DecimalField(max_digits=25,decimal_places=15)
    lng = models.DecimalField(max_digits=25,decimal_places=15)
    name = models.CharField(max_length=150,null=True)
    address = models.TextField(max_length=350,null=True)
    type = models.CharField(max_length=150,blank=True,null=True)

class PrefenceOfUser(models.Model):
        user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
        place_detail = models.ForeignKey(Preference, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.user.username
    
        class Meta:
            unique_together = ('user', 'place_detail',)

这是我的 apiview 的 json i post :

 {
        "lat": "29.621142463088336",
        "lng": "52.520185499694527",
        "name":"cafesama1",
        "address":"streetn1",
        "type":"cafe"
       
    }

在 views.py 中:

class PreferedLocationsOfUsers(APIView):
   
    def post(self, request, format=None):
        serializer = PreferLocationSerializer(data=request.data)
        if serializer.is_valid():

                location= Preference(**serializer.data)
                location.save()
                user_perefeces = PrefenceOfUser(user=request.user,place_detail=location)
                user_perefeces.save()
            return Response({'location saved'},status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我想阻止用户在数据库中保存重复的记录,但是当位置对象保存在 PrefenceOfUser 中时 unique_together 不会阻止重复。知道为什么吗?

根据评论,您确实遇到了迁移问题。删除重复项,重新运行 迁移,直到没有错误并且一切正常。

但是,我会把它作为一个模型设计问题来解决。您不需要为此求助于手动约束。

    class Preference(models.Model):

        lat = models.DecimalField(max_digits=25,decimal_places=15)
        lng = models.DecimalField(max_digits=25,decimal_places=15)
        name = models.CharField(max_length=150,null=True)
        address = models.TextField(max_length=350,null=True)
        type = models.CharField(max_length=150,blank=True,null=True)
        users = models.ManyToManyField(get_user_model(), blank=True)

以上代码与您的代码具有完全相同的含义,更简洁,更像 Djangoesque。

您仍然可以通过 Preference.users.through 访问您所谓的 PrefenceOfUser。如果您打算向选择添加更多属性(即用户何时添加他们的偏好),您可以这样做:

    class PrefenceOfUser(models.Model):
        user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
        place_detail = models.ForeignKey(Preference, on_delete=models.CASCADE)
        extra_field = models.WhateverField()
    
        def __str__(self):
            return self.user.username

并将 Preference.users 更改为

models.ManyToManyField(get_user_model(), through=PrefenceOfUser)

仍然会保证唯一性