django-import-exportを使ってみてdjangoにcsvデータを追加

## はじめに
この記事ではdjango-import-exportのライブラリを使って，自作で作成したcsvファイルをdjangoに読みとる記事です．django-import-exportは管理画面からcsvファイルをimportしたりexportしたりできるライブラリです．これを用いて今回はBook,Publisherなどのモデルを作成し，これと関連する(一対一や一体多)csvファイルを読みとらせることまでをやります．加えて，使ってみた所感を記述していきたいと思います．

公式サイト： [django-import-export](https://django-import-export.readthedocs.io/en/stable/index.html)

### 対象者

・ 自分で作ったcsvファイルのデータをdjangoのモデルに保存させたい人
・ django-import-exportを使って見ようと思ったけどうまくいかなかった人
・ データベースの一対一や多対一の内容について知っている人


### 環境
以下のパッケージをインストールしてください．

```
pip install django django-import-export
```
## 目次
1. プロジェクト作成
2. アプリ作成
3. csvファイル作成
4. importしてみる


## プロジェクト作成

### 基本構成

```
django-admin startproject config .
python manage.py startapp Book
```
上記のコマンドでプロジェクトとモデルができるので，settings.pyにて追加app及びモジュールを記述します．


```python
# config/settings.py

INSTALLED_APPS = [
    "import_export",#django-import-exportを使うのに必要
    "Book",#今回作成したapp
]
```

### アプリ
今回はモデルを三個作成します．先ほど作成したBookのmodelsの中に以下のように記述します．

```python
#Book/models.py
from django.db import models
class Publisher(models.Model):
    name = models.CharField("出版社名",max_length=100,help_text="出版社")

class Book(models.Model):
    title = models.CharField("タイトル",max_length=100,help_text="本のタイトル")
    publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE)

class BookPrice(models.Model):
    book = models.OneToOneField(Book,on_delete=models.CASCADE)
    price = models.IntegerField("定価",help_text="本の定価")
```
モデルの内容は以下の通りです．
・　BookはPublisherと一体多の関係
・　BookPriceとBookは一対一の関係

### django-import-exportの出番
これらのモデルにcsvファイルをimportさせるには管理画面から設定します．ここで登場するのがdjango-import-exportです．具体的な方法はadminを少し弄るだけで完了です．

```python
#Book/admin.py
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportMixin
from .models import Book,BookPrice,Publisher

class PublisherAdmin(ImportMixin,admin.ModelAdmin):
    class PublisherResource(resources.ModelResource):
        class Meta:
            model = Publisher
            fields = ("id","name",)
    resource_class = PublisherResource

class BookAdmin(ImportMixin,admin.ModelAdmin):
    class BookResource(resources.ModelResource):
        class Meta:
            model = Book
            fields = ("id","title","publisher",)
    resource_class = BookResource


class BookPriceAdmin(ImportMixin,admin.ModelAdmin):
    class BookPriceResource(resources.ModelResource):
        class Meta:
            model = BookPrice
            fields = ("id","book","price",)
    resource_class = BookPriceResource



admin.site.register(Publisher,PublisherAdmin)
admin.site.register(Book,BookAdmin)
admin.site.register(BookPrice,BookPriceAdmin)
```
**Resourceでimportするcsvファイルの詳細を設定します．fieldsには読み取るカラムを記述します．fields以外にもimport_id_fieldsなどがあり，idの指定を命じ的に行えたりします．その他にもcsvだけのformatを受け付けるものや，データに変更があった場合もimportをするかどうかを変更できたりします．


### csvファイル作成
ここからはExcelにて三つのcsvファイルを作成します．以下のように他のモデルを指し示す時は連携するid番号を書くことにより，連携させることが可能となります．例えば，Bookの『君の声』と『君の音』は出版社中川文庫のオブジェクトを示しています．BookPriceのBookは一対一の関係にあるため，BookPriceとbookのid番号は同じになります．

#### モデル：Publisher
<img width="1393" alt="スクリーンショット 2020-04-24 18.10.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460757/fecbed49-c38c-9d3e-96c7-3e9e3cd217ab.png">

#### モデル：Book
<img width="1393" alt="スクリーンショット 2020-04-24 18.27.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460757/f7aa31ab-3c50-ea8c-87e0-455bf64f8d0b.png">

#### モデル：BookPrice
<img width="1108" alt="スクリーンショット 2020-04-24 18.41.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460757/c8f94765-e765-a4ec-c261-fb763aa24939.png">

### importしてみる

```
python manage.py createsuperuser #色々聞かれるけど書かれている通りぽちぽちする
python manage.py runserver
```
djangoの管理画面に行くと先ほど作成した三つのモデルが管理画面に写っていると思います．この中のPublisherをクリックしてもらうと，以下のような画面が表示されます．
![スクリーンショット 2020-04-24 18.48.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460757/4992005b-9a04-5b13-0337-e383f56e35d0.png)
この画面の右上にIMPORTと表示されているので，ここからimportしていきます．すると，自分で作成していったモデルが登録されていきます．モデルとの連携もされているので確認してみてください．

## 終わりに
この記事てはdjango-import-exportを用いて，データをdjangoのモデル上に登録することをしました．具体的には，モデルを三つ作成しそれぞれが他のモデルと対応する関係にあるがそれらのidを指定することでデータの関係性を保てることを示しました．
次に機会があれば多対多のモデルの作成もやってみたいと思います．