You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Admin导入CSV时ForeignKey字段NOT NULL约束失败问题

Django Admin导入含ForeignKey的CSV时触发NOT NULL约束错误(仅Admin面板出现)

在使用django-import-export库通过Django Admin面板导入CSV数据到项目时,导入含ForeignKey关联的Copy模型记录时,始终出现NOT NULL constraint failed: catalog_copy.book_id错误。该问题仅在Admin面板出现,通过Django Shell导入则完全正常。已确认CSV无问题,模型与资源文件也无异常,推测是Admin面板在实际导入前的逻辑出现异常。

点击“提交”按钮时就会触发错误,甚至无法进入“确认导入”步骤。

错误信息

每一行记录都触发如下错误:

Line number: 1 - NOT NULL constraint failed: catalog_copy.book_id
Line number: 2 - NOT NULL constraint failed: catalog_copy.book_id
...

相关代码

models.py

from django.db import models
from django.core.exceptions import ValidationError

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    isbn = models.CharField(max_length=13)

class Format(models.Model):
    name = models.CharField(max_length=100)

class Copy(models.Model):
    book = models.ForeignKey(Book, related_name='copies', on_delete=models.CASCADE)
    format = models.ForeignKey(Format, related_name='copies', on_delete=models.CASCADE)
    location = models.CharField(max_length=100)
    is_available = models.BooleanField(default=True)

resources.py

from import_export import resources
from .models import Copy

class CopyResource(resources.ModelResource):
    class Meta:
        model = Copy
        fields = ('id', 'book', 'format', 'location', 'is_available')
        import_id_fields = ['id']

    def before_import_row(self, row, **kwargs):
        book_title = row.get('Book Title')
        isbn = row.get('ISBN')
        author = row.get('Author')
        format_name = row.get('Format')
        
        book, created = Book.objects.get_or_create(
            title=book_title,
            defaults={'isbn': isbn, 'author': author}
        )
        format, created = Format.objects.get_or_create(
            name=format_name
        )

        row['book'] = book.pk
        row['format'] = format.pk

admin.py

from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from .models import Copy
from .resources import CopyResource

class CopyAdmin(ImportExportModelAdmin):
    resource_class = CopyResource

admin.site.register(Copy, CopyAdmin)

Shell导入验证(成功)

已通过以下Shell命令成功导入CSV:

import tablib
from catalog.resources import CopyResource

with open('library_copies.csv', 'r', encoding='utf-8') as f:
    data = tablib.Dataset().load(f.read(), format='csv')

resource = CopyResource()
result = resource.import_data(data, dry_run=False)

if result.has_errors():
    print("Errors occurred during the import:")
    for error in result.base_errors:
        print(f"Base error: {error.error}")
else:
    print("The import would proceed without errors.")

日志对比

对比Shell与Admin面板的日志,发现Admin面板未执行CopyResource中的逻辑,尽管面板显示使用的是CopyResource。

Shell日志片段

0.000) BEGIN; args=None; alias=default
(0.000) SAVEPOINT "s8585724224_x6"; args=None; alias=default
...
Before importing row... OrderedDict({'id': '1', 'Book Title': 'Thank You for My Service ', ...})
(0.000) SELECT "catalog_book"."id", ... FROM "catalog_book" WHERE "catalog_book"."title" = 'Thank You for My Service ' LIMIT 21; ...

Admin面板日志片段

(0.000) BEGIN; args=None; alias=default
(0.000) SAVEPOINT "s6196490240_x1"; args=None; alias=default
...
(0.000) INSERT INTO "catalog_copy" ("book_id", "format_id", ...) VALUES (NULL, NULL, '', 1) RETURNING "catalog_copy"."id"; ...

内容的提问来源于stack exchange,提问作者Billy Groble

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:07:37