【问题标题】:Django QuerySet TypeErrorDjango QuerySet 类型错误
【发布时间】:2017-11-30 10:52:19
【问题描述】:

我们遇到了有史以来最奇怪的错误。我们整个开发团队过去两天都在处理这个问题,我们无法克服它。

我们的 DRF 序列化器具有以下功能:

def get_custom_fields(self, obj):
    custom_fields = obj.company.ticketcustomfieldtype_set.all()
    return [{
        'id': field.id,
        'name': str(field.name),
        'type': field.type,
        'value': obj.custom_fields[str(field.id)] if str(field.id) in obj.custom_fields else None
    } for field in custom_fields]

custom_fields 有一个常规的 Django QuerySet

现在奇怪的是:在本地主机上,这工作得很好。在远程,它只有在 QuerySet 为空时才能正常工作。如果里面有东西,我们会得到以下错误:

TypeError:字符串索引必须是整数

custom_fields 现在似乎是一个字符串。我们不知道为什么,因为在本地它工作得很好......

  • Django 1.11.5
  • DRF 3.6.4
  • Python 3.4.3
  • Postgres 9.6.5

非常感谢任何帮助,变得绝望:(

编辑:

TicketCustomFieldType 模型:

class TicketCustomFieldType(models.Model):
    TICKET_CUSTOM_FIELD_TYPES = (
        ('CHAR', _('Text field')),
        ('DATE', _('Date field'))
    )

    TICKET_DEFAULT_CUSTOM_FIELD_TYPE = 'CHAR'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)

    company = models.ForeignKey(
        to=Company,
        verbose_name=_('Company')
    )

    name = I18nCharField(
        verbose_name=_('Name'),
        max_length=80,
    )

    type = models.CharField(
        verbose_name=_('Field type'),
        max_length=20,
        choices=TICKET_CUSTOM_FIELD_TYPES,
        default=TICKET_DEFAULT_CUSTOM_FIELD_TYPE,
        help_text=_('In this field, you can store either text, or date value.'),
    )

    priority = models.IntegerField(default=0)

票型(略):

from django.contrib.postgres.fields import JSONField
from django.core.serializers.json import DjangoJSONEncoder
(...)
class Ticket(models.Model):
    (...)
    custom_fields = JSONField(encoder=DjangoJSONEncoder, default=dict, verbose_name=_('Custom fields'))

    def get_custom_field(self, field_type):
        qs = self.customfields.filter(type=field_type)
        if qs.exists():
            return qs.first()

        new_field = TicketCustomField()
        new_field.ticket = self
        new_field.type = field_type
        new_field.save()
        return new_field

    def get_all_custom_fields(self):
        custom_fields = []
        for type in self.company.ticketcustomfieldtype_set.all():
            custom_fields.append(self.get_custom_field(type))
        return custom_fields

编辑 2:

升级到 Python 3.6 后,这个问题得到了修复,代码没有变化...

【问题讨论】:

  • 看看你的模型定义会很有帮助,你能把它添加到问题中吗?
  • 错误提示obj.custom_fields 是一个列表,而不是字典。因此你可以做obj.custom_fields[1],但是obj.custom_fields[str(1)]会给你一个错误。
  • 谢谢。我已经添加了模型。

标签: python django postgresql django-rest-framework


【解决方案1】:

请更改:

'value': obj.custom_fields[str(field.id)] if str(field.id) in obj.custom_fields else None

对此:

'value': obj.custom_fields[field.id] if str(field.id) in obj.custom_fields else None

这是因为它需要一个整数,但你提供的是一个字符串

【讨论】:

  • 谢谢。不,这不是问题。 custom_fields 应该是 dict 并且该构造没有任何问题。问题是custom_fields 显然不是dict,而是string。错误在列表理解中,而不是在作业中。
  • 可以贴出模型结构吗?而你正在调用 obj.custom_fields,这会返回什么?
  • 谢谢。我已经添加了模型。
猜你喜欢
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2017-05-02
  • 2019-03-25
  • 2014-01-13
  • 2022-06-17
  • 1970-01-01
相关资源
最近更新 更多