Skip to main content
 首页 » 编程设计

python之Reportlab 不在 Google App Engine 上的 Django 应用程序中生成图表

2025年05月04日25lidabo

我有一个在谷歌应用引擎上运行的 Django 应用程序。该应用程序的一项功能是根据使用该应用程序时提供给它的数据生成图表。我使用 reportlab 生成图表,这在开发过程中起作用。但是,在将应用程序上传到 Google App Engine 时,任何查看图表页面的尝试都会返回以下错误:

“导入错误... 没有名为 _renderPM 的模块”

到目前为止,我了解到该错误是由于 reportlab 依赖 GAE 不支持的 PIL 而导致的。我已将 reportlab 模块放在应用程序的项目目录中,但它仍然不起作用。

因此,我的问题是:我需要做什么才能使图表在应用程序上可见?有没有办法让 reportlab 按照我的应用程序的要求在 GAE 上运行?

(应用程序的“mycharts.py”和“views.py”的代码如下所示。)

我的图表.py

from reportlab.graphics.shapes import Drawing, String 
from reportlab.graphics.charts.barcharts import VerticalBarChart 
from reportlab.graphics.charts.linecharts import HorizontalLineChart 
from reportlab.graphics.charts.lineplots import LinePlot 
from reportlab.graphics.widgets.markers import makeMarker 
from reportlab.graphics.charts.textlabels import Label 
from reportlab.graphics.widgets.grids import Grid, DoubleGrid 
from reportlab.lib import colors 
from models import Caller 
 
#Customer gender filter functions begin here 
def male_caller_count(): 
    return Caller.objects.filter(gender='Male').count() 
 
def female_caller_count(): 
    return Caller.objects.filter(gender='Female').count() 
#Customer gender filter functions end here 
 
class GenderChartDraw(Drawing): 
    def __init__(self, width=500, height=500, *args, **kw): 
 
        Drawing.__init__(self,width,height,*args,**kw) 
 
        female = female_caller_count() 
        male   = male_caller_count() 
 
        data = [(male, 0), (0, female)] 
 
        self.add(VerticalBarChart(), name='chart') 
        self.add(String(100,450,'Caller by Gender'), name='title') 
        self.title.fontName = 'Helvetica-Bold' 
        self.title.fontSize = 20 
 
        self.chart.x = 70 
        self.chart.y = 20 
        self.chart.width = 300 
        self.chart.height = 400 
        self.chart.data = data 
        self.chart.strokeColor = colors.black 
        self.chart.valueAxis.valueMin = 0 
        self.chart.valueAxis.valueMax = 50 
        self.chart.valueAxis.valueStep = 5 
        self.chart.valueAxis.visibleGrid = 1 
        self.chart.categoryAxis.style = 'stacked' 
        self.chart.categoryAxis.categoryNames = ['Male', 'Female'] 
        self.chart.bars[0].fillColor = colors.HexColor('#376BF9') 
        self.chart.bars[1].fillColor = colors.HexColor('#FE03E5') 
        self.chart.categoryAxis.labels.fontSize = 13 
 
if __name__=='__main__': 
    #use the standard 'save' method to save barchart.gif, barchart.pdf etc 
    #for quick feedback while working. 
    GenderChartDraw().save(formats=['gif','png','jpg','pdf'],outDir='.',fnRoot='barchart') 

View .py

from django.shortcuts import render, render_to_response 
from django.http import HttpResponse, HttpResponseRedirect 
from django.template import RequestContext 
from django.views.decorators.csrf import csrf_exempt 
from datetime import datetime 
from models import Caller 
import mycharts 
from django.contrib.auth.decorators import login_required 
 
@login_required 
def app_stats(request): 
    return render_to_response('AppStats.html', context_instance=RequestContext(request)) 
 
@login_required 
def gender_chart(request): 
    #instantiate a drawing object 
    d = mycharts.GenderChartDraw() 
 
    if 'height' in request: 
        d.height = int(request['height']) 
    if 'width' in request: 
        d.width = int(request['width']) 
 
    if 'numbers' in request: 
        strNumbers = request['numbers'] 
        numbers = map(int, strNumbers.split(','))     
        d.chart.data = [numbers]   #bar charts take a list-of-lists for data 
 
    if 'title' in request: 
        d.title.text = request['title'] 
 
    #get a GIF (or PNG, JPG, or whatever) 
    binaryStuff = d.asString('gif') 
    return HttpResponse(binaryStuff, 'image/gif') 

错误日志

ImportError at /CallApp/stats/GenderChart/ 
No module named _renderPM 
see https://www.reportlab.com/software/opensource/rl-addons/ 
Request Method: GET 
Request URL:    http://cacallapp.appspot.com/CallApp/stats/GenderChart/ 
Django Version: 1.4.3 
Exception Type: ImportError 
Exception Value:     
No module named _renderPM 
see https://www.reportlab.com/software/opensource/rl-addons/ 
Exception Location: /base/data/home/apps/s~cacallapp/1.365898222031464318/reportlab/graphics/renderPM.py in <module>, line 32 
Python Executable:  /python27_runtime/python27_dist/python 
Python Version: 2.7.3 
Python Path:     
['/base/data/home/apps/s~cacallapp/1.365898222031464318', 
 '/python27_runtime/python27_dist/lib/python27.zip', 
 '/python27_runtime/python27_dist/lib/python2.7', 
 '/python27_runtime/python27_dist/lib/python2.7/plat-linux2', 
 '/python27_runtime/python27_dist/lib/python2.7/lib-tk', 
 '/python27_runtime/python27_dist/lib/python2.7/lib-old', 
 '/python27_runtime/python27_dist/lib/python2.7/lib-dynload', 
 '/python27_runtime/python27_dist/lib/python2.7/site-packages', 
 '/python27_runtime/python27_lib/versions/1', 
 '/python27_runtime/python27_lib/versions/third_party/PIL-1.1.7', 
 '/python27_runtime/python27_lib/versions/third_party/PIL-1.1.7/PIL', 
 '/python27_runtime/python27_lib/versions/third_party/django-1.4', 
 '/python27_runtime/python27_lib/versions/third_party/webapp2-2.3', 
 '/python27_runtime/python27_lib/versions/third_party/webob-1.1.1', 
 '/python27_runtime/python27_lib/versions/third_party/yaml-3.10', 
 '/base/data/home/apps/s~cacallapp/1.365898222031464318/..'] 
Server time:    Tue, 12 Mar 2013 08:38:21 +0000 

回溯

/python27_runtime/python27_lib/versions/third_party/django-1.4/django/core/handlers/base.py in get_response 
                        response = callback(request, *callback_args, **callback_kwargs) ... 
▶ Local vars 
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/contrib/auth/decorators.py in _wrapped_view 
                return view_func(request, *args, **kwargs) ... 
▶ Local vars 
/base/data/home/apps/s~cacallapp/1.365898222031464318/CallApp/views.py in gender_chart 
    binaryStuff = d.asString('gif') 
 ... 
▶ Local vars 
/base/data/home/apps/s~cacallapp/1.365898222031464318/reportlab/graphics/shapes.py in asString 
            from reportlab.graphics import renderPM 
 ... 
▶ Local vars 
/base/data/home/apps/s~cacallapp/1.365898222031464318/reportlab/graphics/renderPM.py in <module> 
                                    "see https://www.reportlab.com/software/opensource/rl-addons/") 
 ... 
▶ Local vars 

请您参考如下方法:

默认情况下,PIL 不会随 SDK 安装,因为许多应用不需要它。尝试安装 PIL:

https://developers.google.com/appengine/docs/python/images/installingPIL

此外,您是否在 app.yaml 中指定了 PIL:

libraries: 
- name: PIL 
  version: "latest"