Photoアプリケーション

23457 ワード

フォトアプリケーションを開発し、写真をアルバムに組み合わせて管理し、各写真に関する情報を登録して表示することができます.
写真サムネイルを処理するには、新しいカスタムフィールドが必要なので、Pillowライブラリを使用してカスタムフィールドを作成する必要があります.

デザイン


表のデザイン


  • Albumテーブル


  • Photoテーブル

  • 1枚のアルバムは複数の写真を持つことができ、1枚の写真は1枚のアルバムにしか属しないため、以下の関係を確立する.
    Album表-1:N Photo表

    URLデザイン



    フォトアプリケーションフレームワーク


    フォトアプリケーションの作成

    python manage.py startapp photo

    INSTALLED APPS登録

        'photo.apps.PhotoConfig',
    

    モデルコーディング


    models.py

    admin.py


    定義された
  • テーブルがAdminサイトに表示されます.pyファイル
  • AlbumAdminは、
  • Adminサイトの外観を定義し、
  • はPhotoAdminクラスを定義します.
    外部キーで接続されたAlbumテーブルとPhotoテーブルの間には1:Nの関係があるため、アルバムオブジェクトを表示すると、オブジェクトに関連する写真オブジェクトが同時に表示されます.同様に表示されるフォーマットは、縦列形式Stackedlnlineと、テーブルのように行形式でリストされたTabularlnlineです.

    fields.py


    写真を保存するThumbnail ImageField Customフィールドの作成
    カスタムフィールドを作成する場合、通常は既存の類似フィールドを継承して作成しますが、画像に関連するカスタムフィールドはImageFieldクラスを継承して作成します.ImageFieldフィールドは、ファイルシステムに画像ファイルを書き込み、削除する必要があるため、ImageField Fileクラスと、2つのクラスを関連付けるコードが必要です.


    DBに反映


    2つのテーブルが新しく定義されたので、DBに反映されます.


    admin.pyファイルで定義したStackedIn lineの設定に従って、入力フォーマットは縦に追加され、追加の設定に従って、1枚のアルバムに2枚の写真のフォーマットを入力できます.

    URLConf符号化


    BookMarkApp/urls.py

  • /photo/URLリクエスト、
  • photoappに処理を依頼するAPP URLCONF
    既存のURLモードにおいて
  • の静的(対応するURLモードを返して静的ファイルを処理する関数)関数が返すURLモードを追加
  • .
    urlpatterns = [
        path('', HomeView.as_view(), name='home'),
        path('admin/', admin.site.urls),
        path('bookmark/', include('bookmark.urls')),
        path('blog/', include('blog.urls')),
        path('photo/', include('photo.urls')),
    ] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) 
    
    setting.MEDIA URLとして定義された/media/URL要求を受信した場合、django.views.static.serve()ビュー関数で処理し、このビュー関数にdocument root=settingsを設定します.MEDIA ROOTキーワードパラメータが渡されます.
    static.serve()関数は開発が容易で,httpd,nginxなどのWebサーバプログラムがよく用いられる.

    photo/urls.py

    app_name = 'photo'
    
    urlpatterns = [
        # /photo/
        path('', views.AlbumLV.as_view(), name='index'),
    
        # /photo/album/
        path('album/', views.AlbumLV.as_view(), name='album_list'),
    
        # /photo/album/99
        path('album/<int:pk>/', views.AlbumDV.as_view(), name='album_detail'),
    
        # /photo/photo/99/
        path('photo/<int:pk>/', views.PhotoDV.as_view(), name='photo_detail'),
    ]

    Viewエンコーディング

    class AlbumLV(ListView):
        model = Album
    
    class AlbumDV(DetailView):
        model = Album
    
    class PhotoDV(DetailView):
        model = Photo

    テンプレートエンコーディング


    ビューにテンプレートファイル名が指定されていないため、デフォルトのテンプレート名はalbum listです.html, album_detail.html, photo_detail.htmlを作成します.

    album_list.html


    各アルバムのアルバム情報と、アルバム内の5枚の写真の画面が表示されます.

    album_detail.html


    特定のアルバムのすべての写真のテンプレートを印刷します.

    photo_detail.html


    特定の写真情報を印刷する画面
    {% extends "base.html" %}
    
    {% block title %}photo_detail.html{% endblock %}
    
    {% block content %}
        <h2 class="mt-5">{{ object.title }}</h2>
    
        <div class="row">
          	<-- 원본 이미지 -->
            <div class="col-md-9">
                <a href="{{ object.image.url }}">
                    <img src="{{ object.image.url }}" style="width: 100%;">
                </a>
            </div>
    
            <ul class="col-md-3 mt-3">
                <li class="h5">Photo Description</li>
                    {% if object.description %}
                        <p>{{ object.description|linebreaks }}</p>
                    {% else %}
                        <p>(blank)</p>
                    {% endif %}
    
                <li class="h5">Date Uploaded</li>
                    <p class="font-italic">{{ object.upload_dt }}</p>
                <li class="h5">Album Name</li>
                    <p class="font-italic">
                        <a href="{% url 'photo:album_detail' object.album.id %}">
                            {{ object.album.name }}
                        </a>
                    </p>
            </ul>
        </div>
    
    {% endblock %}

    base.htmlの変更


    photo:インデックスを指すurlを追加する
    <li class="nav-item mx-1 btn btn-primary">
                            <a class="nav-link" text-white href="{% url 'photo:index' %}">Photo</a>
                        </li>

    サムネイルの作成の変更


    以前はPILを使用してサムネイルを作成していましたが、django-imagekitを使用するとより簡単にサムネイルを作成できます.
  • pip install django-imagekit
  • settings.pyにimagekit
  • を追加
  • models.pyクリスタル
  • class Photo(models.Model):
        album = models.ForeignKey(Album, on_delete=models.CASCADE)
        title = models.CharField('TITLE', max_length=30)
        description = models.TextField('Photo Description', blank=True)
        image = models.ImageField(upload_to='photo/%Y/%m')
        image_thumbnail = ImageSpecField(source='image',
                                         processors=[ResizeToFill(1024,1024)],
                                         format='JPEG')
        upload_dt = models.DateTimeField('Upload Date', auto_now_add=True)
    
        class Meta:
            ordering = ('title',)
    
        def __str__(self):
            return self.title
    
        def get_absolute_url(self):
            return reverse('photo:photo_detail', args=(self.id,))
    ResizeToFillの値を上げるとサムネイルの画質が良くなりました!
    でもロード速度が遅くなったみたい…?
  • テンプレートで写真を撮ります.image_thumbnail.urlとして
  • を使用



    出典:Djangoで学んだPythonネットワークプログラミング(実戦編)-金錫勲
    https://sss20-02.tistory.com/40