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)
仍然会保证唯一性
我有两个这样的模型:
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)
仍然会保证唯一性