62032


Mac, Python3, Django, PostgreSQLを利用して、ローカル環境でWEBアプリを開発しています。

csvファイルをアップロードして、その内容をデータベースに保存するという動きをさせたいのですが、エラーが出てうまく動きません。  
コード等は、こちらのサイトを参考にさせてもらって、ほぼ同じ内容のコードにしていますが、エラーが出てしまいます。

参考サイト）<https://narito.ninja/blog/detail/60/#postindex>

解決の方法について、ご教授いただけないでしょうか？

エラーは、/importのディレクトリで、csvファイルを選択して、送信ボタンをサブミットする時に出ます。

エラー内容：

[code]

    ValueError at /import/
    invalid literal for int() with base 10: '\ufeff1'
    
[/code]

アップロードしているCSVファイルの内容：  
エンコード:UTF-8

[code]

    101,おはよう
    102,こんにちは
    103,こんばんは
    
[/code]

settings.py

[code]

    INSTALLED_APPS = [
        'db_weather.apps.DbWeatherConfig',
    ]
    
[/code]

urls.py:

[code]

    from django.urls import path
    from . import views
    
    app_name = 'db_weather'
    urlpatterns = [
        path('', views.PostIndex.as_view(), name='index'),
        path('import/', views.PostImport.as_view(), name='import'),
        path('export/', views.post_export, name='export'),
    ]
    
[/code]

forms.py

[code]

    from django import forms
    
    
    class CSVUploadForm(forms.Form):
        file = forms.FileField(label='CSVファイル', help_text='※拡張子csvのファイルをアップロードしてください。')
    
[/code]

views.py

[code]

    import csv
    import io
    from django.http import HttpResponse
    from django.urls import reverse_lazy
    from django.views import generic
    from .forms import CSVUploadForm
    from .models import Post
    
    
    class PostIndex(generic.ListView):
        template_name = 'post_list.html'
        model = Post
    
    
    class PostImport(generic.FormView):
        template_name = 'import.html'
        success_url = reverse_lazy('app:db_weather')
        form_class = CSVUploadForm
    
        def form_valid(self, form):
            # csv.readerに渡すため、TextIOWrapperでテキストモードなファイルに変換
            csvfile = io.TextIOWrapper(form.cleaned_data['file'], encoding='utf-8')
            reader = csv.reader(csvfile)
            # 1行ずつ取り出し、作成していく
            for row in reader:
                post, created = Post.objects.get_or_create(pk=row[0])
                post.title = row[1]
                post.save()
            return super().form_valid(form)
    
    
    def post_export(request):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="posts.csv"'
        # HttpResponseオブジェクトはファイルっぽいオブジェクトなので、csv.writerにそのまま渡せます。
        writer = csv.writer(response)
        for post in Post.objects.all():
            writer.writerow([post.pk, post.title])
        return response
    
[/code]

import.html

[code]

    {% extends 'base.html' %}
    
    {% block content %}
    <form action="" method="POST" enctype="multipart/form-data">
      {{ form.as_ul }}
      {% csrf_token %}
      <button type="submit">送信</button>
    </form>
    {% endblock %}
    
[/code]

実行環境  
Mac: mojave 10.14.6  
Python: 3.7.5  
Django: 2.2.2  
PostgreSQL:12.1


CC BY-SA 4.0
2020-01-04T13:49:23.457
61972
2020-01-07T16:53:27.373
36988
question
python python3 django csv
[ invalid literal for int() with base 10: '\ufeff1' ]のエラーが出て、csvファイルをアップロードできない。

[code]

    invalid literal for int() with base 10: '\ufeff1'
    
[/code]

のエラーは views.py を以下の様に変更する事が正しい対応でした。

[code]

    csvfile = io.TextIOWrapper(form.cleaned_data['file'], encoding='utf_8_sig')
    
[/code]

参考としたサイトはこちらです。

[djangoにて日本語のcsvをインポートする方法 - teratail](https://teratail.com/questions/91520)


CC BY-SA 4.0
2020-01-07T08:40:32.077
62032
2020-01-07T16:53:27.373
2020-01-07T16:53:27.373
3060
36988
61972
answer