Djangoを勉強してみる_ミニSNSを作る_その2

Pocket

前回に引き続きSNSアプリを作成していきます。

SNSアプリの内容は以下の本を参考にしています。

参考

Python Django3超入門 (日本語) 単行本 – 2020/6/13 掌田 津耶乃 (著)

コードは前回の続きで作成していますので、初めから作成したい方は以下を参照してください。

Djangoを勉強してみる_ミニSNSを作る_その1

今回の目的

前回はモデルを作成しましたので、今回はSNSアプリのフォームを準備します。

フォームの準備をする 

forms.pyのファイルを新規作成してコードを書いていきます。

1.forms.pyを新規作成

ファイル:sample_app>sns>forms.py

コード:

from django import forms
from.models import Message,Group,Friend,Good
from django.contrib.auth.models import User

#Messageのフォーム(未使用)
class MessageForm(forms.ModelForm):
    class Meta:
        model = Message
        fields = ['owner', 'group', 'content']

#Groupのフォーム(未使用)
class GroupForm(forms.ModelForm):
    class Meta:
        model = Group
        fields = ['owner', 'title']

#Friendのフォーム(未使用)
class FriedForm(forms.ModelForm):
    class Meta:
        model = Friend
        fields = ['owner', 'user', 'group']

#Goodのフォーム(未使用)
class GoodForm(forms.ModelForm):
    class Meta:
        model = Good
        fields = ['owner', 'message']

#Groupのチェックボックスフォーム
class GroupCheckForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        super(GroupCheckForm, self).__init__(*args, **kwargs)
        public = User.objects.filter(username='public').first()
        self.fields['groups'] = forms.MultipleChoiceField(choices=[(item.title, item.title) for item in Group.objects.filter(owner__in=[user,public])],
        widget=forms.CheckboxSelectMultiple(),)

#Groupの選択メニューフォーム
class GroupSelectForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        super(GroupSelectForm, self).__init__(*args, **kwargs)
        self.fields['groups'] = forms.ChoiceField(choices=[('-','-')] + [(item.title, item.title) for item in Group.objects.filter(owner == user)],
        widget=forms.Select(attrs={'class':'form-control'}),)

#Friendのチェックボックスフォーム
class FriendsForm(forms.Form):
    def __init__(self, user, friend = [], vals = [], *args, **kwargs):
        super(FriendsForm, self).__init__(*args, ** kwargs)
        self.fields['friends'] = forms.MultipleChoiceField(choices=[(item.user, item.user) for item in friends],
        widget=forms.CheckboxSelectMultiple(),
        initial=vals)

#Group作成フォーム
class CreateGroupForm(forms.Form):
    group_name = forms.CharField(max_length=50,\
        widget=forms.TextInput(attrs={'class':'form-control'}))

#投稿フォーム
class PostForm(forms.Form):
    content = forms.CharField(max_length=500,\
        widget=forms.Textarea(attrs={'class' :'form-control', 'rows':2}))

    def __init__(self, user, *args, **kwargs):
        super(PostForm, self).__init__(*args, **kwargs)
        public = User.objects.filter(username='public').first()
        self.fields['groups'] = forms.ChoiceField(choices=[('-','-')] + [(item.title, item.title) for item in Group.objects.filter(owner__in=[user,public])],
        widget=forms.Select(attrs={'class':'form-control'}))

Groupのチェックボックスフォームについて解説します。
まず「def __init__(self, user, *args, **kwargs):」ですが、initというのはインスタンスを作成するときに呼び出される初期化メソッドです。

今回は、selfのあとにuserという引数を準備しています。この引数はGroupを取得するUserを引数として渡すためのものです。

次に「super(GroupCheckForm, self).__init__(*args, **kwargs)」です。ここではsuperというメソッドを使います。
superとは、親クラスのメソッドを子クラスでも利用ようになります。

「public = User.objects.filter(username=’public’).first()」は、public変数にusernameがpublicのものを検索し一番最初のものをfirstで取り出しています。

「self.fields[‘group’] = forms.MultipleChoiceField(choices=[(item.title, item.title) for item in Group.objects.filter(owner__in=[user,public])],
widget=forms.CheckboxSelectMultiple(),)」ですが、まず変数としてself.fields[‘group’]でgroupという新規のフィールドを準備しています。
そして、フォームに複数選択可能なMultipleChoiceFieldを準備してchoicesで選択する項目を準備します。
choicesの中身は繰り返し分のfor文を使って、ownerがuserかpublicのgroupを検索して、検索した項目を選択項目としています。

その他のクラスも同じような考え方で作成しています。

続いて、urlを書いていきます。

2.urls.pyを新規作成

ファイル:sample_app>sns>urls.py

コード:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:page>', views.index, name='index'),
    path('groups', views.groups, name='groups'),
    path('add', views.add, name='add'),
    path('creategroup', views.creategroup, name='creategroup'),
    path('post', views.post, name='post'),
    path('share/<int:share_id>', views.share, name='share'),
    path('good/<int:good_id'>, views.good, name='good'),
]

続いてプロジェクト側のurls.pyを編集します。

3.プロジェクトのurls.pyを編集

ファイル:sample_app>sample_app>urls.py

コード:

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', include('hello.urls')),
    path('sns/', include('sns.urls')), #追加
]

snsの部分を追加しました。

今回は長いのでここまでとします。

次回はメインとなるviews.pyを作成していきます。

以上です。ありがとうございました。

P.S.

勉強を継続することが苦手ですか?

少し前からココナラというサービスで習慣化のテクニックについて教えるサービスを始めました。

もし、いつも3日坊主で終わってしまうという方や、ダイエットを続けたい、勉強したい、運動したいなど何か習慣化したいと思っている方がいましたら全力でサポートしますので、まずは覗いてみてください。

すでに何人かの方に実践してもらって効果が出ているという感想をいただいてます。

人生変わる?【習慣化の方法】を教えます 【残り1名】ダイエット、勉強、運動を続けることが苦手ですか?

Pocket

Djangoを勉強してみる_ミニSNSを作る_その1

Pocket

前回までで一通りの基本的なDjangoの使い方を勉強しました。

今回からは今まで勉強したことを使ってミニSNSを作ってみたいと思います。
内容は参考の本を元に作ります。

Djangoの勉強内容は以下の本を参考にしています。

参考

Python Django3超入門 (日本語) 単行本 – 2020/6/13 掌田 津耶乃 (著)

今回の目的

上でも書きましたが、簡単なミニSNSを作ってみようと思います。

アプリケーション概要

今回作成するアプリケーションの概要は次のような感じです。

  • ログイン機能を準備する
  • グループとフレンド機能を準備する
  • 投稿機能とシェア機能を準備する
  • 未ログインでも見ることができるグループを用意する
  • 「いいね」機能を準備する

アプリケーションを作成する

アプリケーションの準備をする 

まずは「sample_app」プロジェクトにアプリケーションを作成します。

1.snsアプリケーションの作成

python manage.py startapp sns

2.作成したアプリケーションを登録する

ファイル:sample_app>sample_app>settings.py

コード:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello',
    'sns', #追加
]

これでアプリケーションの準備が終わったので、次はデータベースの設計をします。

データベースを設計

今回作成するSNSに必要なデータの項目としては次のようになります。

  • ユーザアカウント
    今回はDjangoの管理機能を使うため作成は不要です。

  • 投稿メッセージ
    SNSに投稿するメッセージに必要なテーブルを洗い出します。
    ・投稿者ID
    ・投稿先のグループ
    ・コンテンツ
    ・シェアした時のID
    ・いいねした数
    ・シェアされた数
    ・投稿日時

  • グループ
    グループ機能に必要なテーブルを洗い出します。
    ・投稿者ID
    ・グループ名

  • フレンド
    フレンド機能とはユーザとグループのつながりを管理するためのものです。
    フレンド機能に必要なテーブルを洗い出します。
    ・投稿者ID
    ・バインドされるユーザアカウント
    ・登録されているグループID

  • いいね
    いいね機能に必要なテーブルを洗い出します。
    ・いいねした投稿者ID
    ・いいねしたメッセージID

以上で設計は終わりなので、実際にコードを書いていきます。

モデルを作成する

モデルを作成するためmodels.pyにコードを書いてマイグレーションまで行います。

1.models.pyを編集する

ファイル:sample_app>sns>models.py

コード:

from django.db import models
from django.contrib.auth.models import User

#Messageクラス
class Message(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='message_owner')
    group = models.ForeignKey('Group', on_delete=models.CASCADE)
    content = models.TextField(max_length=1000)
    shared_id = models.IntegerField(default=-1)
    good_count = models.IntegerField(default=0)
    shared_count = models.IntegerField(default=0)
    pub_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.content) + '(' + str(self.owner) + ')'

    def get_share(self):
        return Message.objects.get(id=self.shared_id)

    class Meta:
        ordering = ('-pub_date',)

#Groupクラス
class Group(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='group_owner')
    title = models.CharField(max_length=100)

    def __str__(self):
        return '<' + self.title + '(' + str(self.owner) + '>'

#Friendクラス
class Friend(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friend_owner')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.user) + '(group:"' + str(self.group) + '")'

#Goodクラス
class Good(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='good_owner')
    message = models.ForeignKey(Message, on_delete=models.CASCADE)

    def __str__(self):
        return 'good for "' + str(self.message) + '"(by' + str(self.owner) +')'

今まで勉強してきた内容なので詳細には触れませんが、MessageクラスのMetaクラスのところだけ説明します。

以下のorderingは指定した項目を小さい順(日付の古い順)から並べますが、今回は「-」という記号がついています。この場合は逆順つまり大きい順(日付の新しい順)から並べることになります。

「ordering = (‘-pub_date’,)」

モデルを作成したのでマイグレーションを行います。

2.マイグレーションファイルを作成して実行します。

まずは作成から、

python manage.py makemigrations sns

続いて実行します。

python manage.py migrate

最後に管理ツールから操作できるようにします。

3.admin.pyを編集

ファイル:sample_app>sns>admin.py

コード:

from django.contrib import admin
from .models import Message,Friend,Group,Good

admin.site.register(Message)
admin.site.register(Friend)
admin.site.register(Group)
admin.site.register(Good)

以上で登録が完了したのでログインして確認します。

動作確認

python manage.py runserver

ブラウザで以下にアクセスします。

http://localhost:8000/admin

画面に、Friends、Goods、Groups、Messagesが表示されていれば正常に動作しています。

あとは、管理ユーザを作成します。

管理ツールでユーザを登録する

Authentication and Authorization>User>Addをクリック

ここでは、以下ユーザを作成し「SAVE」をクリックします。

Username:Public
Password:任意のパスワード

以下の情報を登録し、「SAVE」をクリックします。

First name:public
Last name:public
Email address:public@test.co.jp

あとは実際に使うユーザーを3ユーザーほど作成しておきます。

・サンプルユーザ1
・サンプルユーザ2
・サンプルユーザ3

実際に利用するユーザは「Staff status」のチェックをONにしてください。

続いて、publicのGroupを作成します。

publicグループを作成する

管理ツール>SNS>Groups>Addをクリックします。

以下の情報を入力し、「SAVE」をクリックします。

Owner:public
Title:public

publicグループが作成できたところで、本日はここまでとします。

次回はアプリケーションのプログラムを作成していきます。

以上です。ありがとうございました。

P.S.

勉強を継続することが苦手ですか?

少し前からココナラというサービスで習慣化のテクニックについて教えるサービスを始めました。

もし、いつも3日坊主で終わってしまうという方や、ダイエットを続けたい、勉強したい、運動したいなど何か習慣化したいと思っている方がいましたら全力でサポートしますので、まずは覗いてみてください。

すでに何人かの方に実践してもらって効果が出ているという感想をいただいてます。

人生変わる?【習慣化の方法】を教えます 【残り1名】ダイエット、勉強、運動を続けることが苦手ですか?

Pocket