Django序列化器拼接Office对象与字符串报错问题咨询
问题解决:TypeError与Office ID获取方案
1. 报错根源
你遇到的TypeError: unsupported operand type(s) for +: 'Office' and 'str'是因为:
- 你的User模型中
officeid是关联Office模型的ForeignKey字段,所以self.context["request"].user.officeid返回的是Office模型实例对象,而非字符串类型的办公室ID。 - 字符串拼接要求操作数都是字符串,用实例对象和字符串做
+运算自然触发类型错误。 - 而
userid是字符串类型字段,所以拼接能正常执行。
2. 正确拼接cl_itemid的方案
要获取Office的主键值(即你需要的OSA部分),直接访问Office实例的office_id属性即可:
修改Serializer的create方法中cl_itemid的拼接代码:
def create(self, validated_data): validated_data["office"] = self.context["request"].user.officeid validated_data["recorded_by"] = self.context["request"].user.userid # 直接访问Office实例的office_id属性获取字符串ID validated_data["cl_itemid"] = f"{self.context['request'].user.officeid.office_id}-{validated_data.get('sy')}-{validated_data.get('sem')}" return super().create(validated_data)
3. 优化Office实例的字符串显示
你用str(validated_data.get('office'))得到"(Office object (OSA)1)",是因为Django模型默认的__str__方法返回格式为"模型名 object (主键值)"。如果想让实例转字符串直接返回ID,可以重写Office模型的__str__方法:
class Office(models.Model): office_id = models.CharField(primary_key=True, max_length=50) office_name = models.CharField(max_length=200) office_head = models.CharField(max_length=8, blank=True, null=True) designation = models.TextField(blank=True, null=True) office_parent = models.CharField(max_length=50, blank=True, null=True) deptlogo = models.TextField(blank=True, null=True) class Meta: managed = False db_table = 'office' # 重写__str__方法,直接返回office_id def __str__(self): return self.office_id
之后就可以用str(self.context["request"].user.officeid)来获取ID字符串,拼接代码也可以写成:
validated_data["cl_itemid"] = f"{str(self.context['request'].user.officeid)}-{validated_data.get('sy')}-{validated_data.get('sem')}"
4. 移除外键后正常运行的原因
移除User与Office的外键关联后,user.officeid变成了普通字符串字段(直接存储OSA这类ID值),自然可以直接和字符串拼接。但这种做法不推荐——外键关联能保证数据的完整性和一致性,避免无效的办公室ID存入数据库。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

