今回は restaurants というアプリを作成し進めていきます。

CSVのファイルは管理画面のレストランの一覧画面 http://127.0.0.1:8000/admin/restaurants/restaurant/ からアップ。

アプリの作成

python manage.py startapp restaurants

モデルは restaurant で作成。

Admin テンプレートの Override

templatesフォルダは manage.py と同じ階層に作成。

templates/admin/restaurants/restaurant/change_list.html を作成

{% extends 'admin/change_list.html' %}
{% load static %}
{% block content %}

<a href="upload-csv/">Upload a csv file</a>

{{ block.super }}
{% endblock %}

{{ block.super }} は親のテンプレートコンテンツ。

Django change_list.html

Custom Admin Page の作成

上記で作成したリンク先の upload-csv/ の URL を設定

restaurants/admin.py の RestaurantAdmin で get_urls()を設定。

def get_urls(self):
    urls = super().get_urls()
    new_urls = [
        path('upload-csv/', self.upload_csv),
    ]
    return new_urls + urls

Django ドキュメント

templates/admin/csv_upload.htmlを作成

{% extends 'admin/base.html' %}
{% block content %}
<div>
    <form action="." method="POST" enctype="multipart/form-data">
    {{ form.as_p }}
    {% csrf_token %}
    <button type="submit">Upload File</button>
    </form>
</div>
{% endblock %}

csvファイルからのテーブル作成

RestaurantAdmin の get_urlsに記載した upload_csv の処理を追加。

def upload_csv(self, request):

    if request.method == 'POST':
        csv_file = request.FILES['csv_upload']

        file_data = csv_file.read().decode('utf-8')
        restaurants_data = file_data.split('\n')

        for i in restaurants_data:
            fields = i.split(",")
            restaurant.objects.update_or_create(
                name=fields[0],
                address=fields[1],
                )
                
    form = CsvImportForm()
    data = {'form': form}
    return render(request, 'admin/csv_upload.html', data)

update_or_create() を使用するので、 同じオブジェクトがあればアップデートされ、なければ作成される。

フォームも必要なので、restaurants/admin.py にフォームも用意。 class CsvImportForm(forms.Form): csv_upload = forms.FileField()

これで最低限のCSVからデータをアップロードできるかと思います。