86175


お世話になります。

サッカーゲームの選手閲覧作成を目指して、作成を行っております。

現在、django-import-exportにてCSVインポートをする為に、  
CSVの作成とadmin内容の設定を行なっております。

今回、django-import-exportを使用するにあたり、  
下記文献を参考に、adminの内容を設定致しました。

参考文献  
<https://tech.fragment.co.jp/python/django/django-import-export/>  
<https://qiita.com/d_kvn/items/463787f80ea906e955b1>

恐らくForeignKeyとManyToManyのadminの記載の誤りが原因で、  
下記エラーが発生しているかと思うのですが、  
CSVのカラム項目の変更及びadminのカラム名称の変更を行なっても  
同様のエラーが発生しているため、どの点でエラーが発生しているのか、  
知れる方法があれば、ご教示頂けると幸いです。

宜しくお願い致します。

**エラー内容**

[code]

    Traceback (most recent call last):   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/resources.py", line 676, in import_row
        diff = self.get_diff_class()(self, original, new)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/resources.py", line 227, in __init__
        self.left = self._export_resource_fields(resource, instance)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/resources.py", line 248, in _export_resource_fields
        return [resource.export_field(f, instance) if instance else "" for f in resource.get_user_visible_fields()]   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/resources.py", line 248, in <listcomp>
        return [resource.export_field(f, instance) if instance else "" for f in resource.get_user_visible_fields()]   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/resources.py", line 888, in export_field
        return field.export(obj)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/fields.py", line 122, in export
        value = self.get_value(obj)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/import_export/fields.py", line 87, in get_value
        value = getattr(value, attr, None)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 536, in __get__
        return self.related_manager_cls(instance)   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 851, in __init__
        raise ValueError('"%r" needs to have a value for field "%s" before '   File "/Users/mm/e_football2022/django/e_football2022/myvenv/lib/python3.8/site-packages/django/db/models/base.py", line 519, in __repr__
        return '<%s: %s>' % (self.__class__.__name__, self)
    
    TypeError: __str__ returned non-string (type NoneType)
    
[/code]

**CSV内容**  
[![画像の説明をここに入力](https://i.stack.imgur.com/v9T0g.png)](https://i.stack.imgur.com/v9T0g.png)

**インポート画面**  
[![画像の説明をここに入力](https://i.stack.imgur.com/4fjJz.jpg)](https://i.stack.imgur.com/4fjJz.jpg)

**models.py**

[code]

    class RarityCategory(models.Model):
      rarity = models.CharField('レアリティ',max_length=100, blank=True, null=True)
    
      def __str__(self):
            return str(self.rarity)
    
    class PositionCategory(models.Model):
      position = models.CharField('ポジショングループ',max_length=100, blank=True, null=True)
    
      def __str__(self):
            return str(self.position)
    
    class ClubCategory(models.Model):
      clubname = models.CharField('クラブグループ',max_length=100, blank=True, null=True)
    
      def __str__(self):
            return str(self.clubname)
    
    class LeagueCategory(models.Model):
      leaguename = models.CharField('リーググループ',max_length=100, blank=True, null=True)
    
      def __str__(self):
            return str(self.leaguename)
    
    class PlayStyleCategory(models.Model):
      playstyle = models.CharField('プレースタイルグループ', max_length=30, blank=True, null=True)
    
      def __str__(self):
            return str(self.playstyle)
    
    class Skill(models.Model):
        player_skill = models.CharField('スキル名', max_length=20, blank=True, null=True)
    
        def __str__(self):
            return str(self.player_skill)
    
    class Player(models.Model):
        new_date_field = models.DateTimeField('リリース日', blank=True, null=True)
        initial = models.IntegerField('初期総合値', blank=True, null=True)
        maximum = models.IntegerField('最大総合値', blank=True, null=True)
        level = models.IntegerField('最大レベル', blank=True, null=True)
        player_name = models.CharField('選手名', max_length=50, blank=True, null=True)
        country = models.CharField('国名', max_length=30, blank=True, null=True)
        age = models.IntegerField('年齢', blank=True, null=True)
        height = models.IntegerField('身長', blank=True, null=True)
        dominant_foot = models.CharField('利き足', max_length=2, blank=True, null=True)
        player_image = models.ImageField(upload_to='images', verbose_name='プレイヤー画像', null=True, blank=True)
        position_group = models.ForeignKey(PositionCategory, verbose_name='ポジショングループ' ,on_delete=models.PROTECT)
        rarity_group = models.ForeignKey(RarityCategory, verbose_name='レアリティ' ,on_delete=models.PROTECT)
        club_group = models.ForeignKey(ClubCategory, verbose_name='クラブグループ' ,on_delete=models.PROTECT)
        league_group = models.ForeignKey(LeagueCategory, verbose_name='リーググループ' ,on_delete=models.PROTECT)
        playstyle_group = models.ForeignKey(PlayStyleCategory, verbose_name='プレースタイルグループ' ,on_delete=models.PROTECT)
        skill = models.ManyToManyField(Skill, verbose_name='スキル' , blank=True)
    
        def __str__(self):
            return self.player_name
    
[/code]

**admin.py**

[code]

    from import_export import fields, resources
    from import_export.admin import ImportExportModelAdmin
    from import_export.resources import ModelResource
    from import_export.widgets import ForeignKeyWidget, ManyToManyWidget
    from import_export.fields import Field
    
    class PositionCategoryResource(resources.ModelResource):
        class Meta:
            model = PositionCategory
    
    # Costモデルに統合する為にModelResourceを継承したクラスを作成
    class ClubCategoryResource(resources.ModelResource):
        class Meta:
            model = ClubCategory
    
    class LeagueCategoryResource(resources.ModelResource):
        class Meta:
            model = LeagueCategory
    
    class RarityCategoryResource(resources.ModelResource):
        class Meta:
            model = RarityCategory
    
    # Shopモデルに統合する為にModelResourceを継承したクラスを作成
    class PlayStyleCategoryResource(resources.ModelResource):
        class Meta:
            model = PlayStyleCategory
    
    # Costモデルに統合する為にModelResourceを継承したクラスを作成
    class SkillResource(resources.ModelResource):
        class Meta:
            model = Skill
    
    class PlayerResource(resources.ModelResource):
        position_group = Field(attribute='position_group', column_name='position_group_id', widget=ForeignKeyWidget(PositionCategory, 'id'))
        rarity_group = Field(attribute='rarity_group', column_name='rarity_group_id', widget=ForeignKeyWidget(RarityCategory, 'id'))
        club_group = Field(attribute='club_group', column_name='club_group_id', widget=ForeignKeyWidget(ClubCategory, 'id'))
        league_group = Field(attribute='league_group', column_name='league_group_id', widget=ForeignKeyWidget(LeagueCategory, 'id'))
        playstyle_group = Field(attribute='playstyle_group', column_name='playstyle_group_id', widget=ForeignKeyWidget(PlayStyleCategory, 'id'))
        skill = Field(attribute='skill', column_name='skill_id', widget=ManyToManyWidget(Skill, field='id'))
        class Meta:
            model = Player
            import_order = ('id', 'new_date_field', 'initial', 'maximum', 'level', 'player_name', 'country', 'age', 'height', 'dominant_foot', 'player_image', 'position_group', 'rarity_group', 'club_group', 'league_group', 'playstyle_group', 'skill')
            import_id_fields = ['id']
    
    @admin.register(RarityCategory)
    # ImportExportModelAdminを継承したadminクラスを作成
    class RarityCategoryAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'rarity')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = RarityCategoryResource
    
    
    @admin.register(PositionCategory)
    # ImportExportModelAdminを継承したadminクラスを作成
    class PositionCategoryAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'position')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = PositionCategoryResource
    
    
    @admin.register(ClubCategory)
    # ImportExportModelAdminを継承したadminクラスを作成
    class ClubCategoryAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'clubname')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = ClubCategoryResource
    
    @admin.register(LeagueCategory)
    # ImportExportModelAdminを継承したadminクラスを作成
    class LeagueCategoryAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'leaguename')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = LeagueCategoryResource
    
    
    @admin.register(PlayStyleCategory)
    # ImportExportModelAdminを継承したadminクラスを作成
    class PlayStyleCategoryAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'playstyle')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = PlayStyleCategoryResource
    
    
    @admin.register(Skill)
    # ImportExportModelAdminを継承したadminクラスを作成
    class SkillAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'player_skill')
    
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = SkillResource
    
    @admin.register(Player)
    # ImportExportModelAdminを継承したadminクラスを作成
    class PlayerImportAdmin(ImportExportModelAdmin):
        ordering = ['id']
        list_display=('id', 'new_date_field', 'initial', 'maximum', 'level', 'player_name', 'country', 'age', 'height', 'dominant_foot', 'player_image', 'position_group', 'rarity_group', 'club_group', 'league_group', 'playstyle_group', 'skill')
        filter_horizontal = ('skill',)
        # resource_classにModelResourceを継承したクラスを設定
        resource_class = PlayerResource
    
        def skill(self, row):
            return ','.join([x.player_skill for x in row.meta.all()])
    
[/code]


CC BY-SA 4.0
2022-02-05T02:52:13.883
86152
2022-02-06T11:50:38.517
48697
question
python django
django-import-exportのCSVインポートエラーがどこで発生しているのか知りたい。


現時点ではありますが、  
ForeignKeyWidgetの設定を下記の内容に変更を行なうことで、  
インポートすること自体は成功致しました。

[code]

    class PlayerResource(resources.ModelResource):
    position_group = Field(attribute='position_group', column_name='position_group_id',widget=ForeignKeyWidget(PositionCategory))
    rarity_group = Field(attribute='rarity_group', column_name='rarity_group_id',widget=ForeignKeyWidget(RarityCategory))
    club_group = Field(attribute='club_group', column_name='club_group_id',widget=ForeignKeyWidget(ClubCategory))
    league_group = Field(attribute='league_group', column_name='league_group_id',widget=ForeignKeyWidget(LeagueCategory))
    playstyle_group = Field(attribute='playstyle_group', column_name='playstyle_group_id',widget=ForeignKeyWidget(PlayStyleCategory))
    skill = Field(attribute='skill', column_name='skill_id',widget=ManyToManyWidget(Skill))
    class Meta:
        model = Player
        fields = ('id', 'new_date_field', 'initial', 'maximum', 'level', 'player_name', 'country', 'age', 'height', 'dominant_foot', 'player_image', 'position_group', 'rarity_group', 'club_group', 'league_group', 'playstyle_group', 'skill')
        import_id_fields = ['id']
    
[/code]

但し、new_date_fieldとskillのManyToManyWidgetが取り込みができない状況です。  
引き続き自己解決が出来るように取り組めればと思いますので、  
一旦、こちらの質問はこの回答を持って、解決済みにしたいと思います。

また上記2点で解決出来ない点があれば、ご質問させて頂けると幸いです。  
宜しくお願い致します。


CC BY-SA 4.0
2022-02-06T11:04:01.297
86175
2022-02-06T11:50:38.517
2022-02-06T11:50:38.517
3060
48697
86152
answer