1

我有一个看起来像这样的 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 代码,或者这是否尽可能快?

4

3 回答 3

1
  1. 当然,您不需要返回所有城市,因为您可能无论如何都不会显示所有 30000 行(至少以用户友好的方式)。考虑一个解决方案,您只返回请求位置的某个范围内的城市。Mongo 支持地理空间索引,所以这样做应该没有问题。互联网上也有很多关于如何在 Django/MongoDB 中执行空间过滤的教程。

    def GetAllCities(request, lon, lat):
    
        #Pseudo-code
        cities = City.objects.filterWithingXkmFromLonLat(lon, lat).all() 
    
        cities = serializers.serialize("json", cities) 
        return HttpResponse(cities)
    
  2. 如果您真的非常需要所有城市,请考虑缓存响应。城市的位置、名称和人口都不是动态变化的,比方说几秒钟。缓存结果并仅每小时、每天或更长时间重新计算。Django 支持开箱即用的缓存

    @cache_page(60 * 60)
    def GetAllCities(request):
       (...)
    
于 2013-04-26T11:18:35.893 回答
0

您可以尝试加快速度的另一件事是从 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()
于 2013-04-26T12:10:30.403 回答
0

找到解决方案

我正在使用不同的方法进行基准测试,一种方法是查看一种语言/框架选择数据库中的所有行并将其作为 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

在这里找到了解决方案

于 2013-04-27T07:35:45.067 回答