2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Djangoでダミーの画像データを生成して投稿する

Last updated at Posted at 2020-05-02

#はじめに

私はDjangoをUdemyから勉強、遊びで触っている程度なので、UdemyのDjango講座のTODOアプリと社内SNSを自分なりに改良しているところなのでレベル的にはそのあたりと変わらないと思います。
【徹底的に解説!】Djangoの基礎をマスターして、3つのアプリを作ろう!

なので実用性など全く度外視で動くものを作るという考えでやっております。
初めての記事で至らぬ点やわかりにくいところも多々あると思いますが生暖かい目で見守ってくださると幸いです。

#やりたいこと
Djangoに画像データを登録する際、いちいちデータを打ち込んで、画像を選択して...とするのが非常に面倒だったため何か良い方法がないかと思い調べていると

$ python manage.py runscript <ファイル名>

でpythonファイルが実行できると知り、これを使っていくことにしました。
runscriptについては細かくは省きますが、これによりmanage.pyのあるディレクトリにあるscriptsディレクトリの中の任意のファイルのrunメソッドを実行します。
ここではadd_dummies.pyというファイルを作りましたので<ファイル名>にはadd_dummies.pyが入ることになりますね。

#画像の生成
画像を選ぶのが面倒だったため、以下の記事を参考にして画像を生成することにしました。
Python + PILでダミー画像をつくる。

実際に私が生成に用いたコードは以下になります。
アレンジしたところといえば、パッとみで画像の判別がつくように画像の色、サイズを乱数で変更しているところぐらいでしょうか。

add_dummyies.py
from PIL import Image,ImageDraw, ImageFont
import random
colors = [(255,0,0), (0,255,0), (0,0,255),(0,0,0),(255,255,255)]#赤・緑・青・黒・白の色のリスト

def make_image(N):
    """
    画像ファイルを作成
    返り値はファイルの名前
    """
    screen = (200+random.randint(0,100), 200+random.randint(0,100))
    pen_color=random.choice(colors)
    bg_color=random.choice(colors)
    img = Image.new('RGB', screen, bg_color)
    x, y = img.size
    u = x - 1
    v = y - 1
    draw = ImageDraw.Draw(img)
    draw.line((0, 0, u, 0), pen_color)
    draw.line((0, 0, u, v), pen_color)
    draw.line((0, 0, 0, v), pen_color)
    draw.line((u, 0, 0, v), pen_color)
    draw.line((u, 0, u, v), pen_color)
    draw.line((0, v, u, v), pen_color)
    filename="/sample_{}.jpg".format(N)
    img.save("media"+filename)
    return filename

これで任意のn個の画像ファイルを生成し、manage.pyが存在するディレクトリからみて ./media/<画像ファイル>という場所に画像を保存します。

また、このアプリのモデルは以下のように定義しています。

models.py
from django.db import models

class RecommendedBook(models.Model):
    author = models.CharField(max_length=100)
    bookTitle = models.CharField(max_length=50)
    content = models.TextField()
    bookImage=models.ImageField(upload_to="")
    genre = models.CharField(max_length=200, null=True, blank=True, default="")
    good = models.IntegerField(null=True, blank=True,default=0)
    goodtext = models.CharField(max_length=500,null=True,blank=True, default="")
    notGood = models.IntegerField(null=True, blank=True,default=0)
    notGoodtext = models.CharField(max_length=500,null=True,blank=True, default="")

他の要素もついでに保存したかったのでFaker関数などを用いましたが、そこは今回の主題ではないので省きます。
実行するためにadd_dummies.pyに以下のrunメソッドを追記してやります。
他の要素も追加しなければならないため以下のようになりました。

add_dummies.py

from book.models import RecommendedBook
import random,string
from faker import Faker
fakegen=Faker("ja_JP")

genres=["技術書","英語","数学","小説","感動","楽しい"]#ジャンルを適当なリストに設定し、あとでランダムに取り出す

fakegen = Faker()

def run():
    N=5#データを5つほど作成
    for entry in range(N):
        imgfile=make_image(entry)
        bookGenre=random.choice(genres)+" "+random.choice(genres)#二つほどジャンルを設定する
        dummy=RecommendedBook(author=fakegen.name(), bookTitle=fakegen.word(),
                              content=fakegen.text(), genre=bookGenre,
                              bookImage=imgfile
                              )
        dummy.save()

実行して管理画面を覗くと

スクリーンショット 2020-05-02 17.38.52.png

うまく新しいデータが保存されてました!

#終わり
以上で終わりになります!
~~自分なりには調べてみたのですが良い方法が見つからなかったのでこのような泥臭い方法になってしまいました。~~以下に本記事の上位互換がありましたので紹介させていただきます。
Django で ダミー画像ファイルを置かずに Python で作成して画像アップロードのテストをする

また、データを登録するのがforループで回しているためか割と遅いため、ループ数が少なければあまり問題にはなりませんがある程度より多くなってしまうと相当時間がかかってしまうのが大きな問題だと思いました。
「もっと楽にできる方法があるよ!」「こうすれば速くなるよ!」などご教示いただければ嬉しいです
一応本記事のコードがあるgithubのページを置いておきます。

最後まで読んでいただきありがとうございました!

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?