【发布时间】:2020-05-28 13:02:19
【问题描述】:
我有以下型号:
class LocationPoint(models.Model):
latitude = models.DecimalField(max_digits=9, decimal_places=6)
longitude = models.DecimalField(max_digits=9, decimal_places=6)
class Meta:
unique_together = (
('latitude', 'longitude',),
)
交互者:
class GetOrCreateLocationPoint(object):
def exec(self, latitude: Decimal, longitude: Decimal) -> LocationPoint:
point, _ = LocationPoint.objects.get_or_create(
latitude=latitude,
longitude=longitude,
defaults={
'latitude': latitude,
'longitude': longitude,
},
)
return point
并测试:
class GetOrCreateLocationPointTest(TestCase): # from django.test import TestCase
__get_or_create_location_point: GetOrCreateLocationPoint
def setUp(self) -> None:
self.__get_or_create_location_point = GetOrCreateLocationPoint()
def test_create_duplicate(self):
point1 = self.__get_or_create_location_point.exec(Decimal(10.5), Decimal(5.01))
self.__get_or_create_location_point.exec(Decimal(13.4), Decimal(1.5343))
point3 = self.__get_or_create_location_point.exec(Decimal(10.5), Decimal(5.01))
self.assertEqual(point1.pk, point3.pk)
执行point3 = self.__get_or_create_location_point.exec(Decimal(10.5), Decimal(5.01))时出错:
django.db.utils.IntegrityError: duplicate key value violates unique constraint "geo_locationpoint_latitude_longitude_08fb2a82_uniq"
DETAIL: Key (latitude, longitude)=(10.500000, 5.010000) already exists.
但是,如果在调试器中我看到self.model.DoesNotExist 在get_or_create 中被抛出(并处理),则它找不到现有行。
怎么了?
Django 3.0.3,PostgreSQL 12。
【问题讨论】:
-
我有点迷茫,是
get_or_create扔IntegrityError还是DoesNotExist? -
@AustinPilp 它在内部处理
DoesNotExist(参见 get_or_create 实现),尝试创建新行,然后引发IntegrityError -
明白了,我不确定这是否能解决您的问题,但您实际上不需要提供纬度和经度作为默认值。由于它们已经是查找参数,因此它们将包含在新对象中。文档的相关部分 (docs.djangoproject.com/en/3.0/ref/models/querysets/…) 提供了一个有用的“等效代码”示例,说明了如何使用每个参数
-
真可惜,我现在在一台装有 Django 的机器附近,但如果今晚我回家时没有人帮助你,我会试着玩一下,看看能不能弄清楚任何事情。祝你好运!
-
@AustinPhilp 大声笑,刚刚修复它,问题出在浮动中,看看我的回答:D
标签: django postgresql psycopg2 django-orm