Django - 返回 JSON,错误
Posted
技术标签:
【中文标题】Django - 返回 JSON,错误【英文标题】:Django - Return JSON, Error 【发布时间】:2013-04-20 12:55:00 【问题描述】:我有一个看起来像这样的 View.py 函数:
def GetAllCities(request):
cities = list(City.objects.all())
return HttpResponse(json.dumps(cities))
我的城市模型如下所示
class City(models.Model):
city = models.CharField()
loc = models.CharField()
population = models.IntegerField()
state = models.CharField()
_id = models.CharField()
class MongoMeta:
db_table = "cities"
def __unicode__(self):
return self.city
我正在使用一个看起来像这样的 MongoDB
"_id" : ObjectId("5179837cbd7fe491c1f23227"),
"city" : "ACMAR",
"loc" : "[-86.51557, 33.584132]",
"state" : "AL",
"population" : 6055
尝试从 GetAllCities 函数返回 JSON 时出现以下错误:
City ACMAR 不是 JSON 可序列化的
所以我尝试了这个:
def GetAllCities(request):
cities = serializers.serialize("json", City.objects.all())
return HttpResponse(cities)
这可行,但速度很慢,大约需要 9 秒(我的数据库包含 30000 行) 应该花这么长时间还是我做错了什么? 我用 php、Rails 和 NodeJS 构建了相同的应用程序。 在 PHP 中平均需要 2000 毫秒,NodeJS = 800 毫秒,Rails = 5882 毫秒和 Django 9395 毫秒。我试图在这里进行基准测试,所以我想知道是否有办法优化我的 Django 代码,或者这是否尽可能快?
【问题讨论】:
【参考方案1】:当然,您不需要返回所有城市,因为您可能不会显示所有 30000 行(至少以用户友好的方式)。考虑一个解决方案,您只返回请求位置的某个范围内的城市。 Mongo 支持geospatial indexes,所以这样做应该没有问题。网上也有很多关于如何在 Django/MongoDB 中进行空间过滤的教程。
def GetAllCities(request, lon, lat):
#Pseudo-code
cities = City.objects.filterWithingXkmFromLonLat(lon, lat).all()
cities = serializers.serialize("json", cities)
return HttpResponse(cities)
如果您真的非常需要所有城市,请考虑缓存响应。城市的位置、名称和人口都不是动态变化的,比方说几秒钟。缓存结果并仅每小时、每天或更长时间重新计算。 Django支持缓存out of the box
@cache_page(60 * 60)
def GetAllCities(request):
(...)
【讨论】:
这是一个非常好的答案,但我正在做基准测试,看看我的答案:) 即使你缩短了处理时间,你实际上并没有解决问题。如果您将拥有两倍以上的城市,那么时间将增加两倍。【参考方案2】:您可以尝试加快速度的另一件事是从 db 中获取您需要的值并获取 QuerySet 来构建字典。
这样一个简单的查询就可以了:
City.objects.all().values('id', 'city', 'loc', 'population', 'state')
或者你可以把它放在一个经理中:
class CitiesManager(models.Manager):
class as_dict(self):
return self.all().values('id', 'city', 'loc', 'population', 'state')
class City(models.Model):
.... your fields here...
objects = CitiesManager()
然后在你的视图中使用它:
City.objects.as_dict()
【讨论】:
啊啊非常好,试试吧!谢谢【参考方案3】:找到解决方案
我正在使用不同的方法进行基准测试,一种方法是查看一种语言/框架选择数据库中的所有行并将其作为 JSON 返回的速度。我现在找到了一个解决方案,可以将它的速度提高一半!
我的新观点.py
def GetAllCities(request):
dictionaries = [ obj.as_dict() for obj in City.objects.all() ]
return HttpResponse(json.dumps("Cities": dictionaries), content_type='application/json')
还有我的新模型
class City(models.Model):
city = models.CharField()
loc = models.CharField()
population = models.IntegerField()
state = models.CharField()
_id = models.CharField()
def as_dict(self):
return
"id": self.id,
"city": self.city,
"loc": self.loc,
"population": self.population,
"state": self.state
# other stuff
class MongoMeta:
db_table = "cities"
def __unicode__(self):
return self.city
找到解决方案here
【讨论】:
以上是关于Django - 返回 JSON,错误的主要内容,如果未能解决你的问题,请参考以下文章
关于Django中JsonResponse返回中文字典编码错误的解决方案
在 django 1.5 CBV 中返回 HttpResponse 时的 simplejson 错误
在 Django Rest Framework 中找不到资源时返回自定义 404 错误