django "can't adapt type '__proxy__'" 错误信息
django "can't adapt type '__proxy__'" error message
class GenderTypeEnum:
FEMALE = 1
MALE = 2
UNKNOWN = 3
types = (
(FEMALE, _("Female")),
(MALE, _("Male")),
(UNKNOWN, _("Unknown"))
)
class PersonModel(models.Model):
identity = models.CharField(max_length=50, unique=True)
name = models.CharField(max_length=75)
last_name = models.CharField(max_length=75)
gender = models.PositiveIntegerField(choices=GenderTypeEnum.types)
class StaffModel(models.Model):
person = models.ForeignKey('PersonModel', on_delete=models.CASCADE, related_name='staffs')
registration_number = models.CharField(max_length=50, unique=True)
start_date = models.DateField()
finish_date = models.DateField(null=True, blank=True)
我正在使用以下查询来列出员工的性别统计信息
StaffModel.objects.values("person__gender").annotate(count=Count("person__gender"))
输出:
[
{"person__gender":1, "count":1},
{"person_gender":2, "count":5}
]
但是性别字段是一个选择字段,所以我想要的输出是这样的:
[
{"person__gender":1, "gender_exp":"Male", "count":1},
{"person_gender":2, "gender_exp":"Female", "count":5}
]
我通过查看给@bachkoi32 Display name of a choice field in Django while using annotate
的答案创建了以下 class
为了输出,我用这个class:
class WithChoices(Case):
def __init__(self, model, field, condition=None, then=None, **lookups):
fields = field.split('__')
for f in fields:
model = model._meta.get_field(f)
if model.related_model:
model = model.related_model
choices = dict(model.flatchoices)
whens = [When(**{field: k, 'then': Value(v)}) for k, v in choices.items()]
return super().__init__(*whens, output_field=CharField())
我更改了我的查询:
qs = StaffModel.objects.values("person__gender").annotate(gender_exp=WithChoices(StaffModel, 'person__gender'), count=Count("person__gender")).values("person__gender","gender_exp","count")
当我想打印查询结果时,它引发了错误;
django.db.utils.ProgrammingError: 无法适配类型 'proxy'
qs = StaffModel.objects.values("person__gender").annotate(gender_exp=WithChoices(StaffModel, 'person__gender'), count=Count("person__gender")).values("person__gender","gender_exp","count")
print(qs)
# raise error;
# django.db.utils.ProgrammingError: can't adapt type '__proxy__'
您选择的标签是惰性翻译,这些不能作为值传递给查询,需要使用 force_str
将它们转换为字符串
from django.utils.encoding import force_str
class WithChoices(Case):
def __init__(self, model, field, condition=None, then=None, **lookups):
fields = field.split('__')
for f in fields:
model = model._meta.get_field(f)
if model.related_model:
model = model.related_model
choices = dict(model.flatchoices)
whens = [When(**{field: k, 'then': Value(force_str(v))}) for k, v in choices.items()]
return super().__init__(*whens, output_field=CharField())
class GenderTypeEnum:
FEMALE = 1
MALE = 2
UNKNOWN = 3
types = (
(FEMALE, _("Female")),
(MALE, _("Male")),
(UNKNOWN, _("Unknown"))
)
class PersonModel(models.Model):
identity = models.CharField(max_length=50, unique=True)
name = models.CharField(max_length=75)
last_name = models.CharField(max_length=75)
gender = models.PositiveIntegerField(choices=GenderTypeEnum.types)
class StaffModel(models.Model):
person = models.ForeignKey('PersonModel', on_delete=models.CASCADE, related_name='staffs')
registration_number = models.CharField(max_length=50, unique=True)
start_date = models.DateField()
finish_date = models.DateField(null=True, blank=True)
我正在使用以下查询来列出员工的性别统计信息
StaffModel.objects.values("person__gender").annotate(count=Count("person__gender"))
输出:
[
{"person__gender":1, "count":1},
{"person_gender":2, "count":5}
]
但是性别字段是一个选择字段,所以我想要的输出是这样的:
[
{"person__gender":1, "gender_exp":"Male", "count":1},
{"person_gender":2, "gender_exp":"Female", "count":5}
]
我通过查看给@bachkoi32 Display name of a choice field in Django while using annotate
的答案创建了以下 class为了输出,我用这个class:
class WithChoices(Case):
def __init__(self, model, field, condition=None, then=None, **lookups):
fields = field.split('__')
for f in fields:
model = model._meta.get_field(f)
if model.related_model:
model = model.related_model
choices = dict(model.flatchoices)
whens = [When(**{field: k, 'then': Value(v)}) for k, v in choices.items()]
return super().__init__(*whens, output_field=CharField())
我更改了我的查询:
qs = StaffModel.objects.values("person__gender").annotate(gender_exp=WithChoices(StaffModel, 'person__gender'), count=Count("person__gender")).values("person__gender","gender_exp","count")
当我想打印查询结果时,它引发了错误; django.db.utils.ProgrammingError: 无法适配类型 'proxy'
qs = StaffModel.objects.values("person__gender").annotate(gender_exp=WithChoices(StaffModel, 'person__gender'), count=Count("person__gender")).values("person__gender","gender_exp","count")
print(qs)
# raise error;
# django.db.utils.ProgrammingError: can't adapt type '__proxy__'
您选择的标签是惰性翻译,这些不能作为值传递给查询,需要使用 force_str
将它们转换为字符串from django.utils.encoding import force_str
class WithChoices(Case):
def __init__(self, model, field, condition=None, then=None, **lookups):
fields = field.split('__')
for f in fields:
model = model._meta.get_field(f)
if model.related_model:
model = model.related_model
choices = dict(model.flatchoices)
whens = [When(**{field: k, 'then': Value(force_str(v))}) for k, v in choices.items()]
return super().__init__(*whens, output_field=CharField())