Django 调用 'id' 需要一个数字但得到了字符串
Django call 'id' expected a number but got string
django-import-export 库的 Django 错误。
我想通过 django admin 将数据从 excel 导入数据库。我使用它 django-import-export,但我得到了 Field 'id' expected a number 但得到了 'HPI'。
Excel 文件包含
我找到了答案,我必须添加 exclude = ('id'),但没有帮助。我也做了迁移,它也没有帮助。
如何修复它并能够通过 django admin 将 6 列数据从 excel 导入数据库?
models.py
from django_mysql.models import JSONField, Model
from django.db import models
class Category(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.title
class Tag(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
def __str__(self):
return self.title
class Type(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
verbose_name = 'Type'
verbose_name_plural = 'Types'
def __str__(self):
return self.title
class Macro(Model):
type = models.ForeignKey(
Type,
max_length=100,
null=True,
blank=True,
on_delete=models.SET_NULL)
tags = models.ManyToManyField(Tag, blank=True)
category = models.ForeignKey(
Category, null=True, blank=True, on_delete=models.SET_NULL)
abbreviation = models.CharField(max_length=100, unique=True)
title = models.CharField(max_length=100, verbose_name='Title')
content = models.TextField(max_length=1000, null=True, blank=True)
class Meta:
ordering = ('-id',)
def __str__(self):
return self.title
admin.py
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from .models import Category, Tag, Type, Macro
class MacroResource(resources.ModelResource):
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
@admin.register(Macro)
class MacroAdmin(ImportExportModelAdmin):
resource_class = MacroResource
list_display = ('id', 'type', 'tags_list', 'category', 'abbreviation', 'title', 'content')
search_fields = ('title', 'category__title', 'type__title', 'abbreviation', 'content', )
def tags_list(self, obj):
tags = [t for t in obj.tags.all()]
return ' '.join(str(tags)) if tags else '-'
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
def __str__(self):
return self.title
@admin.register(Type)
class TypeAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
Django-import-export 期望第一列为 id
。
如果这些是新对象,只需将 id
列留空即可。否则,将对象的数据库 ID 放入该字段。
如果您不能或不想修改文件,您将总是向数据库添加新行(而不是修改现有行) ,您可以通过覆盖方法 before_import
并强制 get_instance
始终 return False
.
在资源 class 中动态创建一个 id 字段
class MacroResource(resources.ModelResource):
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
dataset.insert_col(0, col=["",]*dataset.height, header="id")
def get_instance(self, instance_loader, row):
return False
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
问题出在数据库模型的 ForeignKey 和 ManyToMany 字段上。所以 django-import-export 库需要为这个字段获取小部件。
解决方法:
admin.py
class MacroResource(resources.ModelResource):
type = fields.Field(
column_name='type',
attribute='type',
widget=ForeignKeyWidget(Type, 'title'))
category = fields.Field(
column_name='category',
attribute='category',
widget=ForeignKeyWidget(Category, 'title'))
tags = fields.Field(
column_name='tags',
attribute='tags',
widget=ManyToManyWidget(Tag, field='title'))
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
import_id_fields = ('title',)
fields = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
而不是
class MacroResource(resources.ModelResource):
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
您在模型中使用外键的属性,
您需要指定父模型的 ID,而不是 xlsx/csv 文件中的值。
django-import-export 库的 Django 错误。
我想通过 django admin 将数据从 excel 导入数据库。我使用它 django-import-export,但我得到了 Field 'id' expected a number 但得到了 'HPI'。
Excel 文件包含
我找到了答案,我必须添加 exclude = ('id'),但没有帮助。我也做了迁移,它也没有帮助。 如何修复它并能够通过 django admin 将 6 列数据从 excel 导入数据库?
models.py
from django_mysql.models import JSONField, Model
from django.db import models
class Category(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.title
class Tag(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
def __str__(self):
return self.title
class Type(Model):
title = models.CharField(max_length=100)
class Meta:
ordering = ('-id',)
verbose_name = 'Type'
verbose_name_plural = 'Types'
def __str__(self):
return self.title
class Macro(Model):
type = models.ForeignKey(
Type,
max_length=100,
null=True,
blank=True,
on_delete=models.SET_NULL)
tags = models.ManyToManyField(Tag, blank=True)
category = models.ForeignKey(
Category, null=True, blank=True, on_delete=models.SET_NULL)
abbreviation = models.CharField(max_length=100, unique=True)
title = models.CharField(max_length=100, verbose_name='Title')
content = models.TextField(max_length=1000, null=True, blank=True)
class Meta:
ordering = ('-id',)
def __str__(self):
return self.title
admin.py
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from .models import Category, Tag, Type, Macro
class MacroResource(resources.ModelResource):
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
@admin.register(Macro)
class MacroAdmin(ImportExportModelAdmin):
resource_class = MacroResource
list_display = ('id', 'type', 'tags_list', 'category', 'abbreviation', 'title', 'content')
search_fields = ('title', 'category__title', 'type__title', 'abbreviation', 'content', )
def tags_list(self, obj):
tags = [t for t in obj.tags.all()]
return ' '.join(str(tags)) if tags else '-'
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
def __str__(self):
return self.title
@admin.register(Type)
class TypeAdmin(admin.ModelAdmin):
list_display = ('id', 'title')
Django-import-export 期望第一列为 id
。
如果这些是新对象,只需将 id
列留空即可。否则,将对象的数据库 ID 放入该字段。
如果您不能或不想修改文件,您将总是向数据库添加新行(而不是修改现有行) ,您可以通过覆盖方法 before_import
并强制 get_instance
始终 return False
.
class MacroResource(resources.ModelResource):
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
dataset.insert_col(0, col=["",]*dataset.height, header="id")
def get_instance(self, instance_loader, row):
return False
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
问题出在数据库模型的 ForeignKey 和 ManyToMany 字段上。所以 django-import-export 库需要为这个字段获取小部件。
解决方法: admin.py
class MacroResource(resources.ModelResource):
type = fields.Field(
column_name='type',
attribute='type',
widget=ForeignKeyWidget(Type, 'title'))
category = fields.Field(
column_name='category',
attribute='category',
widget=ForeignKeyWidget(Category, 'title'))
tags = fields.Field(
column_name='tags',
attribute='tags',
widget=ManyToManyWidget(Tag, field='title'))
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
import_id_fields = ('title',)
fields = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
而不是
class MacroResource(resources.ModelResource):
class Meta:
model = Macro
skip_unchanged = True
report_skipped = True
exclude = ('id', )
export_order = ('type', 'tags', 'category', 'abbreviation', 'title', 'content')
您在模型中使用外键的属性, 您需要指定父模型的 ID,而不是 xlsx/csv 文件中的值。