【问题标题】:How to import django-taggit tag in django-import-export如何在 django-import-export 中导入 django-taggit 标签
【发布时间】:2020-04-22 06:09:25
【问题描述】:

我无法使用 Django-import-export 导入 Django-taggit 标签。

这个错误是在输入值时出现的。

Line number: 1 - invalid literal for int() with base 10: 'def'

此外,此错误是当值为空时。

Line number: 2 - Cannot add <QuerySet []> (<class 'django.db.models.query.QuerySet'>). Expected <class 'django.db.models.base.ModelBase'> or str.

我也在This issue发帖提问。

xlsx表 还有一个id列。

models.py

from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager

class KnowHow(models.Model):    

    author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField(blank=True)
    file = models.FileField(blank=True,upload_to='explicit_knowhows')
    free_tags = TaggableManager(blank=True)

    def __str__(self):
        return self.title

admin.py

from django.contrib import admin
from import_export import resources
from import_export import fields
from import_export.admin import ImportExportModelAdmin

from .models import KnowHow
# Register your models here.

class KnowHowResource(resources.ModelResource):

    class Meta:
        model = KnowHow
        import_id_fields = ['id']

@admin.register(KnowHow)
class knowHowAdmin(ImportExportModelAdmin):
    resource_class = KnowHowResource

【问题讨论】:

    标签: python django python-3.x django-import-export django-taggit


    【解决方案1】:

    我的解决方案:

    自定义小部件:

    from import_export import fields
    from import_export import widgets
    from taggit.forms import TagField
    from taggit.models import Tag
    
    class TagWidget(widgets.ManyToManyWidget):
        def render(self, value, obj=None):
            return self.separator.join(
                [obj.name for obj in value.all()]
            )
    
        def clean(self, value, row=None, *args, **kwargs):
            values = TagField().clean(value)
            return [
                Tag.objects.get_or_create(name=tag)[0]
                for tag in values
            ]
    
    

    那么我们也必须覆盖字段:

    class TagFieldImport(fields.Field):
    
        def save(self, obj, data, is_m2m=False):
            # This method is overridden because originally code
            # getattr(obj, attrs[-1]).set(cleaned, clean=True) doesn't unpack cleaned value
            if not self.readonly:
                attrs = self.attribute.split('__')
                for attr in attrs[:-1]:
                    obj = getattr(obj, attr, None)
                cleaned = self.clean(data)
                if cleaned is not None or self.saves_null_values:
                    if not is_m2m:
                        setattr(obj, attrs[-1], cleaned)
                    else:
                        # Change only here
                        getattr(obj, attrs[-1]).set(*cleaned, clean=True)
    
    

    然后像这样在资源中使用:

        tags = cure_widgets.TagFieldImport(
            attribute="tags",
            column_name="tags",
            widget=cure_widgets.TagWidget(Tag, separator=", ")
        )
    

    【讨论】:

      【解决方案2】:

      我使用的另一种可能的解决方案/解决方法。

      定义一个帮助模型文本字段来存储逗号分隔的标签列表。我们称之为“tags_char”。然后重写模型的save方法,将逗号分隔的列表转换为Tag对象。

      # models.py
      from django.db import models
      from taggit.managers import TaggableManager
      
      class Book(models.Model):
          
          tags_char = models.TextField(blank=True)
          tags = TaggableManager(blank=True)
          
          def save(self, *args, **kwargs):
              if ',' in self.tags_char and self.pk:
                  for tag in self.tags_char.split(','):
                      self.tags.add(tag)
              super(Book, self).save(*args, **kwargs)
      
      

      最后一步是调整 ModelResource。我们从导入中排除标签,而是从文件中导入 tags_char。知道一旦保存对象,转换就会发生。

      #admin.py
      class BookResource(resources.ModelResource):
          class Meta:
              model = Book
              exclude = ('id', 'tags') 
      
      

      不幸的是,这种解决方法存在一个问题。由于 django import-export 的工作方式,在为对象分配 id (pk) 之前调用 save() 方法。如果 id 不存在,则无法添加标签。这就是在 save 方法中检查 self.pk 是否存在的原因。 if ',' in self.tags_char and self.pk

      有三种方法可以解决这个问题。

      1. 如果您要补充数据或在将数据发布到网站之前对其进行审核。您需要手动重新保存它们 => 问题已解决(我就是这种情况)
      2. 只需导入文件两次。第二次围绕 id 的遗嘱存在。
      3. 在要导入的文件中提供一个 ID。

      【讨论】:

        猜你喜欢
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 2015-04-26
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        相关资源
        最近更新 更多