【问题标题】:Django Import-Export Overwriting / Updating non-unique CharFieldDjango 导入导出覆盖/更新非唯一 CharField
【发布时间】:2019-11-24 20:51:04
【问题描述】:

我正在尝试导入在某些情况下缺少数据的 xls 文件。与其在导入之前手动更改必要的字段,不如让 Django 考虑它们。

在这种情况下,虽然每个产品都应该有一个唯一的条形码,但此 xls 文件中的某些产品却有“N/A”。出于某种原因,Django 将这些产品解释为相同,并更新它们而不是创建新产品。

其他 CharFields 不会出现此问题,例如 Format 或 Cost;如果所有条目的格式均为“LP”,则导入继续进行且不会出错。

任何想法是什么原因造成的?

额外问题:有什么方法可以缩短发布日期的时间?

我相信这是所有相关的代码。

resources.py

class ArtistWidget(widgets.ForeignKeyWidget):
    def clean(self, value, row=None, *arg, **kwargs):
        return self.model.objects.get_or_create(artist=value)[0] if value else None


class LabelWidget(widgets.ForeignKeyWidget):
    def clean(self, value, row=None, *args, **kwargs):
        return self.model.objects.get_or_create(label=value)[0] if value else None


class ProductResource(resources.ModelResource):
    artist = fields.Field(column_name='artist', attribute='artist',
                          widget=ArtistWidget(Artist, 'artist'))
    label = fields.Field(column_name='label', attribute='label',
                         widget=LabelWidget(Label, 'label'))
    prod_format = fields.Field(column_name='format', attribute='prod_format')
    release_date = fields.Field(
        column_name='release date', attribute='release_date')
    cat_number = fields.Field(column_name='cat#', attribute="cat_number")

    class Meta:
        model = Product
        import_id_fields = ('barcode',)
        fields = ('artist', 'title', 'cat_number',
                  'prod_format', 'label', 'barcode', 'cost', 'release_date',)
        skip_unchanged = True
        export_order = ['artist', 'title', 'cat_number',
                        'prod_format', 'label', 'barcode', 'cost', 'release_date', ]

    def before_import_row(self, row, **kwargs):
        # Convert Excel Date to datetime
        row['release date'] = datetime.datetime(*xlrd.xldate_as_tuple(
            row['release date'], datemode=0))
        # String Conversions
        row['artist'] = string.capwords(row['artist'])
        row['title'] = string.capwords(row['title'])
        row['label'] = row['label'].upper()

models.py

class Artist(models.Model):
    artist = models.CharField(primary_key=True, max_length=30)


class Label(models.Model):
    label = models.CharField(primary_key=True, unique=True, max_length=30)


class Product(models.Model):
    barcode = models.CharField(
        'UPC/Barcode', max_length=20, blank=True, unique=False)
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE, blank=True)
    title = models.CharField(max_length=30)
    sub_title = models.CharField(max_length=30, blank=True)
    release_date = models.DateField('Release Date', blank=True)
    prod_format = models.CharField('Format', max_length=12)
    label = models.ForeignKey(Label, on_delete=models.CASCADE, blank=True)
    cat_number = models.CharField(
        'Catalogue Number', max_length=12, blank=True)
    cost = models.CharField(max_length=12, blank=True)

【问题讨论】:

  • 你找到解决方案了吗"...从发布日期开始缩短时间?" ?

标签: python django database


【解决方案1】:

它只接受条形码列中的唯一字段的原因是资源中的这个设置:

import_id_fields = ('barcode',)

我与 rstr 模块一起创建了一个 Barcode Widget 来创建随机的 8 位条形码来替换“n/a”:

class BarcodeWidget(widgets.CharWidget):
    def clean(self, value, row=None, *args, **kwargs):
        if value == 'n/a':
            value = rstr.rstr(string.digits, 8)
            return value
        else:
            return value
class ProductResource(resources.ModelResource):
    barcode = fields.Field(column_name='barcode',
                           attribute='barcode', widget=BarcodeWidget())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2021-11-10
    • 2014-06-15
    相关资源
    最近更新 更多