注释字段是str,而不是datetime.datetim

2024-03-28 09:00:01 发布

您现在位置:Python中文网/ 问答频道 /正文

示例

我试图使用相关模型的DateTimeField中的数据来注释对象

    class Author(models.Model):
            name = models.CharField(max_length=256)

    class Book(models.Model):
        name = models.CharField(max_length=256)
        is_published = models.BooleanField()
        publication_date = models.DateTimeField()
        author = models.ForeignKey(Author, on_delete=models.PROTECT)

    queryset = Author.objects.annotate(
        has_unpublished=Exists(
            Book.objects.filter(
                author=OuterRef('pk'),
                is_published=False))
    ).annotate(
        last_published_date=Max(
            'book__publication_date',
            filter=Q(book__is_published=True)
        )
    )

我在默认的本地sqlite3数据库和MySQL(使用mysqlclient)之间切换。SQLite工作,MySQL崩溃

原因是:两个数据库的编译器

results = compiler.execute_sql(**kwargs)

返回int和string元组列表,如下所示:

SQLite

<class 'list'>: [[(1, 'Alice', 1, '2017-01-01 01:00:00'), (2, 'Bob', 0, '2019-01-05 13:00:00'), (3, 'Carol', 1, None), (4, 'Dan', 0, None)]]

MySQL

<class 'list'>: [((1, 'Alice', 1, '2017-01-01 01:00:00.000000'), (2, 'Bob', 0, '2019-01-05 13:00:00.000000'), (3, 'Carol', 1, None), (4, 'Dan', 0, None))]

现在,当SQLite后端看到一个假定的datetime字段时,它会在运行时使用以下方法生成一个转换器:

django.db.backends.sqlite3.operations.DatabaseOperations

    def convert_datetimefield_value(self, value, expression, connection):
        if value is not None:
            if not isinstance(value, datetime.datetime):
                value = parse_datetime(value)
            if settings.USE_TZ and not timezone.is_aware(value):
                value = timezone.make_aware(value, self.connection.timezone)
        return value

这样就行了

但是,MySQL后端执行以下操作:

django.db.backends.mysql.operations.DatabaseOperations

    def convert_datetimefield_value(self, value, expression, connection):
        if value is not None:
            value = timezone.make_aware(value, self.connection.timezone)
        return value

Django然后继续崩溃,试图检查<str>的时区感知

上下文

上面是一个玩具的例子,我用来复制崩溃

在我们实际的生产环境中,MySQL编译器的execute_sql,奇怪的是,如果我请求一个带注释作者的完整列表(action=='list'),它会返回一个带有datetime.datetime对象的“原始”数据元组列表,如果我请求一个特定的作者(action=='retrieve'),它会返回一个带有字符串的相同列表。查询集各自的sql查询仅因存在单个WHERE子句而不同

这让我觉得我做错了什么,没有从驱动程序那里得到我应该得到的原始信息(而不是Django中出现错误的可能性要低得多)

我该怎么办?N+1是不可能的,这将是应用程序的主要操作员视图,datetime字段实际上是一对多关系


Tags: selfnone列表datetimeifisvaluemodels