我已经搜遍过,但找不到好的例子。
我有两个模型,其中一个有ManyToManyField。我试图通过ManyToManyField将需要信息的QuerySet传递到自定义序列化程序并返回JSON响应。
model.py
class Company(models.Model):
"""Company in database."""
founded = models.DateField(null=True)
name = models.CharField(max_length=60)
series = models.CharField(max_length=10, null=True)
valuation = models.DecimalField(max_digits=20, decimal_places=5, null=True)
description = models.TextField(null=True)
def __unicode__(self):
"""Return human-readable representation of company for debugging."""
return '<{}>'.format(self.name)
class Metric(models.Model):
"""Metrics for companies."""
name = models.CharField(max_length=30)
end_date = models.DateField()
start_date = models.DateField()
company = models.ManyToManyField(Company)
value = models.IntegerField()
def __unicode__(self):
"""Return human-readable representation of metric for debugging."""
return '<{}, {}>'.format(self.name, self.company)
views.py
class ClientAPI:
@classmethod
def _serialize(cls, objects):
def create_company_map():
return {c.id: c.name for c in Company.objects.all()}
# Replace company ids with company names
def map_company(obj, company_map):
if 'company' in obj:
obj['company'] = company_map[obj['company']]
return obj
company_map = create_company_map()
raw = serializers.serialize('python', objects)
res = [dict(map_company(obj['fields'], company_map)) for obj in raw]
return res
@classmethod
def get_metrics(cls, request):
all_metrics = Metric.objects.all().order_by('end_date')
serialized_metrics = ClientAPI._serialize(all_metrics)
return JsonResponse(serialized_metrics, safe=False, json_dumps_params=None)
@classmethod
def get_metrics_by_company(cls, request, company_name):
metrics_by_company = Metric.objects.filter(company__name=company_name).order_by('end_date')
serialized_metrics_by_company = ClientAPI._serialize(metrics_by_company)
return JsonResponse(serialized_metrics_by_company, safe=False, json_dumps_params=None)
我无法更改序列化程序,因为我有其他依赖它的方法。当我运行此代码时,我得到:
TypeError:不可用类型:&#39; list&#39;
非常感谢任何有关如何解决此问题的见解!以防万一,这是追溯。
Traceback (most recent call last):
File "/Users/jackiehuynh/anaconda/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/jackiehuynh/anaconda/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/jackiehuynh/Lytmus/question_1/client/views.py", line 167, in get_metrics
serialized_metrics = ClientAPI._serialize(all_metrics)
File "/Users/jackiehuynh/Lytmus/question_1/client/views.py", line 65, in _serialize
res = [dict(map_company(obj['fields'], company_map)) for obj in raw]
File "/Users/jackiehuynh/Lytmus/question_1/client/views.py", line 60, in map_company
obj['company'] = company_map[obj['company']]
TypeError: unhashable type: 'list'
答案 0 :(得分:0)
由于company
是一个m2m字段,因此以下语句中的obj['company']
似乎是一个列表:
obj['company'] = company_map[obj['company']]
并且,您试图通过将列表作为键导致company_map
dict来获取某些值,这会导致此错误。
您可以使用list comprehension从ID中获取公司名称:
obj['company'] = [company_map.get(idx, None) for idx in obj['company']]
您也可以关注this post获取详细说明,如果您愿意,可以在shell中自行尝试:
In [1]: x = {'a': 1}
In [2]: x[[1, 2]]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-1032576b46f9> in <module>()
----> 1 x[[1, 2]]
TypeError: unhashable type: 'list'
答案 1 :(得分:0)
没关系,我可能问了一个不好的问题。原来我想要做的是实际使用ForeignKey,而不是ManyToManyField。无论如何,谢谢你的帮助!