与 django-import-export 的非规范化关系

Denormalising relationships with django-import-export

我有一个预订模型的房间预订应用程序,它与我的房间模型有一个简单的外键关系。这是我正在处理的事情的一个超级简短的想法:

class Room(..):
    floor = models.IntegerField()
    number = models.IntegerField()
    ...

class Booking(..):
    room = models.ForeignKey('Room')
    ...

我一直在 Booking 模型上使用 django-import-export 来让管理员以可以导入 Excel 的方式备份这些数据。它对于快速按需提供数据非常有用,而且不会浪费我的时间。

我的问题是房间关系被忽略了;它抽出 room_id 而不是遵循关系。我理解这对于导入数据有何意义,但对于所有实际的外部目的,Room 的 primary_key 完全没用。查看预订数据的人需要知道它所在的楼层和房间号。

有没有一种简单的方法可以将额外的数据添加到 django-import-export 的数据中,从而从本质上对这些字段进行非规范化?

其实并没有那么痛!我们需要重写 ModelAdmin 上的几个 ImportExportModelAdmin 函数,以将额外数据添加到查询中,然后将其拉入。

class BookingAdmin(ImportExportModelAdmin):
    ...

    def get_resource_class(self):
        from import_export.fields import Field
        rc = super(BookingAdmin, self).get_resource_class()
        for f in ('room_floor', 'room_number'):
            rc.fields[f] = Field(f, f, readonly=True)
        return rc

    def get_export_queryset(self, request):
        rs = super(BookingAdmin, self).get_export_queryset(request)
        return rs.annotate(
            room_floor=F('room__floor'),
            room_number=F('room__number')
        )

不知道导入时会发生什么。我已将这些字段设置为只读,因此它们 应该 被忽略。值得庆幸的是,我们已经过了进口问题的地步。

请参阅文档中的 Getting started

定义 ModelResource 字段时,可以遵循模型关系:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        fields = ('author__name',)

在您的案例中,字段将是 ('room__floor', 'room__number',)