' ManyToOneRel'对象没有属性' parent_model' django chartit错误

时间:2016-02-05 12:55:55

标签: python django highcharts

我有两个模型的django项目:

this

数据库中有很多设备,我想绘制图表"设备数量"每个"设备型号"。

我试图用django chartit来完成这项任务。

view.py中的代码:

class DeviceModel(models.Model):
    name = models.CharField(max_length=255)
    def __unicode__(self):
        return self.name

class Device(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    device_model = models.ForeignKey(DeviceModel)
    serial_number = models.CharField(max_length=255)

    def __unicode__(self):
        return self.device_model.name + " - " + self.serial_number

这似乎是我需要的结果,但它不是设备名称,而是绘制ForeignKey(1,2,3,4 ...)的值,我需要实际的设备型号名称。

我认为解决方案是改变类别'价值观:

ds = PivotDataPool(
    series=[
        {'options': {
            'source':Device.objects.all(),
            'categories':'device_model'
            },
        'terms':{
                u'Amount':Count('device_model'),
            }
        }
    ],
)

pvcht = PivotChart(
    datasource=ds,
    series_options =
          [{'options':{
            'type': 'column',
            'stacking': True
            },
            'terms':[
            u'Amount']
            }],
     chart_options =
          {'title': {
               'text': u'Device amount chart'},
           'xAxis': {
                'title': {
                   'text': u'Device name'}},
           'yAxis': {
                'title': {
                   'text': u'Amount'}}}                    
)


return render(request, 'charts.html', {'my_chart': pvcht})  

但是这给了我错误:

'categories':'device_model__name'

这种类型的引用应该符合官方示例http://chartit.shutupandship.com/demo/pivot/pivot-with-legend/

我在这里缺少什么?

'ManyToOneRel' object has no attribute 'parent_model'
C:\Anaconda\lib\site-packages\django\core\handlers\base.py in get_response
                    response = middleware_method(request, callback, callback_args, callback_kwargs)
                    if response:
                        break
            if response is None:
                wrapped_callback = self.make_view_atomic(callback)
                try:
                                response = wrapped_callback(request, *callback_args, **callback_kwargs)  ###
                except Exception as e:
                    # If the view raised an exception, run it through exception
                    # middleware, and if the exception middleware returns a
                    # response, use that. Otherwise, reraise the exception.
                    for middleware_method in self._exception_middleware:
                        response = middleware_method(request, e)
D:\django\predator\predator\views.py in charts
        series=[
            {'options': {
                'source':Device.objects.all(),
                'categories':'device_model__name'
                },
                #'legend_by': 'device_model__device_class'},
            'terms':{
                                u'Amount':Count('device_model'), ###
                    }
            }
        ],
        #pareto_term = 'Amount'
    )
C:\Anaconda\lib\site-packages\chartit\chartdata.py in __init__
            'terms': {
              'asia_avg_temp': Avg('temperature')}}]

        # Save user input to a separate dict. Can be used for debugging.
        self.user_input = locals()
        self.user_input['series'] = copy.deepcopy(series)

                    self.series = clean_pdps(series) ###
        self.top_n_term = (top_n_term if top_n_term 
                           in self.series.keys() else None)
        self.top_n = (top_n if (self.top_n_term is not None 
                                and isinstance(top_n, int)) else 0)   
        self.pareto_term = (pareto_term if pareto_term in 
                            self.series.keys() else None)
C:\Anaconda\lib\site-packages\chartit\validation.py in clean_pdps

def clean_pdps(series):
    """Clean the PivotDataPool series input from the user.
    """
    if isinstance(series, list):
        series = _convert_pdps_to_dict(series)
                    clean_pdps(series) ###
    elif isinstance(series, dict):
        if not series:
            raise APIInputError("'series' cannot be empty.")
        for td in series.values():
            # td is not a dict
            if not isinstance(td, dict):
C:\Anaconda\lib\site-packages\chartit\validation.py in clean_pdps
            try:
                _validate_func(td['func'])
            except KeyError:
                raise APIInputError("Missing 'func': %s" % td)
            # categories
            try:
                td['categories'], fa_cat = _clean_categories(td['categories'],
                                                                        td['source']) ###
            except KeyError:
                raise APIInputError("Missing 'categories': %s" % td)
            # legend_by
            try:
                td['legend_by'], fa_lgby = _clean_legend_by(td['legend_by'],
                                                           td['source'])
C:\Anaconda\lib\site-packages\chartit\validation.py in _clean_categories
    else:
        raise APIInputError("'categories' must be one of the following "
                            "types: basestring, tuple or list. Got %s of "
                            "type %s instead."
                            %(categories, type(categories)))
    field_aliases = {}
    for c in categories:
                    field_aliases[c] = _validate_field_lookup_term(source.model, c) ###
    return categories, field_aliases
def _clean_legend_by(legend_by, source):
    if isinstance(legend_by, basestring):
        legend_by = [legend_by]
    elif isinstance(legend_by, (tuple, list)):

2 个答案:

答案 0 :(得分:0)

categories中,您只能使用source queryset中包含的字段。 另一方面,您可以使用foreignKey或manyTomany连接字段。

在下面找一个例子。

而不是使用

'source':Device.objects.all()
'categories':'device_model'

尝试使用

'source':DeviceModel.objects.all()
'categories':'name'

和下一个

'Amount':Count('device__device_model')

答案 1 :(得分:0)

我认为较新版本的django(1.8)存在问题。

不推荐使用此代码:

m = field_details[0].related.parent_model

而不是使用

m = field_details[0].getattr(field.related, 'related_model', field.related.model)

您还可以在GitHub上找到解决此问题的方法。

希望这有帮助。