Django REST项目报错TypeError: unhashable type: 'dict'求协助
Django REST项目TypeError: unhashable type: 'dict'问题解决
问题场景
开发Django REST项目时触发TypeError: unhashable type: 'dict'错误,相关代码及错误信息如下:
序列化器代码
class TrasactionSerializer(serializers.Serializer): amount = serializers.IntegerField(validators=[is_amount]) email = serializers.EmailField() wallet = serializers.CharField(source='wallet.id', read_only=True) def validate_email(self, value): if CustomUser.objects.filter(email=value).exists(): return value raise serializers.ValidationError({"detail": "Email not found"}) def save(self): user = self.context['request'].user wallet = WalletModel.objects.get(user=user) data = self.validated_data url = 'https://api.paystack.co/transaction/initialize' headers = { "authorization": f"Bearer {settings.PAYSTACK_SECRET_KEY}" } r = requests.post(url, headers=headers, data=data) response = r.json() walletTransaction.objects.create( wallet=wallet, transaction_type="deposit", amount= data["amount"], paystack_payment_reference=response['data']['reference'], status=response["pending"], )
错误信息
File "/home/olaneat/Desktop/files/project/django/jobConnect/job-connect/wallet/serializers.py", line 59, in save headers = { TypeError: unhashable type: 'dict'
问题原因及修复方案
核心原因
requests.post的data参数用于传递表单编码数据,若传入的validated_data包含嵌套字典这类不可哈希的类型,就会触发该错误。同时Paystack的初始化交易API要求请求体为JSON格式,而非表单格式。
修复步骤
- 将
requests.post中的data=data替换为json=data,requests会自动将数据序列化为JSON,并设置正确的Content-Type: application/json请求头。 - 修正
status字段的取值:Paystack响应中没有pending这个键,正确的状态字段应为response['data']['status'],避免后续触发KeyError。
修正后的save方法代码
def save(self): user = self.context['request'].user wallet = WalletModel.objects.get(user=user) data = self.validated_data url = 'https://api.paystack.co/transaction/initialize' headers = { "authorization": f"Bearer {settings.PAYSTACK_SECRET_KEY}" } # 改用json参数传递JSON格式数据 r = requests.post(url, headers=headers, json=data) response = r.json() walletTransaction.objects.create( wallet=wallet, transaction_type="deposit", amount= data["amount"], paystack_payment_reference=response['data']['reference'], # 修正状态字段取值 status=response['data']['status'], )
内容的提问来源于stack exchange,提问作者Tosin Ayoola
相关产品推荐
相关产品推荐

