pythonanywhereアカウント作成
アプリ作成でmysite2とうゆうdjangoのプロジェクトを作成コンソールを開く
mysite2フォルダまで移動してコンソールを開くsnsとゆうアプリケーションを作成
アプリケーションをmysite2/setting.pyに登録する
mysite2/mysite2/settiong.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'sns', #これを足す
]
モデルを作成する
mysite2/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)
share_id = models.IntegerField(default=-1)
good_count = models.IntegerField(default=0)
share_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.share_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) + ')'
マイグレーションを実行
snsのテーブルを作成
mysite2/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)
管理画面の管理ユーザーを作成
publicユーザーとpublicグループを作成、テストユーザーも作成
フォームの作成
mysite2/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 FriendForm(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, friends=[], 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'}),
)
urls.pyを作成
mysite2/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'),
]
mysite2のurls.pyを修正
mysite2/urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('sns/', include('sns.urls')),
]
views.pyを修正
mysite2/sns/views.py
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib.auth.models import User
from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from .models import Message,Friend,Group,Good
from .forms import GroupCheckForm,GroupSelectForm,\
FriendsForm,CreateGroupForm,PostForm
# indexのビュー関数
@login_required(login_url='/admin/login/')
def index(request, page=1):
# publicのuserを取得
(public_user, public_group) = get_public()
# POST送信時の処理
if request.method == 'POST':
# Groupsのチェックを更新した時の処理
# フォームの用意
checkform = GroupCheckForm(request.user,request.POST)
# チェックされたGroup名をリストにまとめる
glist = []
for item in request.POST.getlist('groups'):
glist.append(item)
# Messageの取得
messages = get_your_group_message(request.user, \
glist, page)
# GETアクセス時の処理
else:
# フォームの用意
checkform = GroupCheckForm(request.user)
# Groupのリストを取得
gps = Group.objects.filter(owner=request.user)
glist = [public_group.title]
for item in gps:
glist.append(item.title)
# メッセージの取得
messages = get_your_group_message(request.user, glist, page)
# 共通処理
params = {
'login_user':request.user,
'contents':messages,
'check_form':checkform,
}
return render(request, 'sns/index.html', params)
@login_required(login_url='/admin/login/')
def groups(request):
# 自分が登録したFriendを取得
friends = Friend.objects.filter(owner=request.user)
# POST送信時の処理
if request.method == 'POST':
# Groupsメニュー選択肢の処理
if request.POST['mode'] == '__groups_form__':
# 選択したGroup名を取得
sel_group = request.POST['groups']
# Groupを取得
gp = Group.objects.filter(owner=request.user) \
.filter(title=sel_group).first()
# Groupに含まれるFriendを取得
fds = Friend.objects.filter(owner=request.user) \
.filter(group=gp)
print(Friend.objects.filter(owner=request.user))
# FriendのUserをリストにまとめる
vlist = []
for item in fds:
vlist.append(item.user.username)
# フォームの用意
groupsform = GroupSelectForm(request.user,request.POST)
friendsform = FriendsForm(request.user, \
friends=friends, vals=vlist)
# Friendsのチェック更新時の処理
if request.POST['mode'] == '__friends_form__':
# 選択したGroupの取得
sel_group = request.POST['group']
group_obj = Group.objects.filter(title=sel_group).first()
print(group_obj)
# チェックしたFriendsを取得
sel_fds = request.POST.getlist('friends')
# FriendsのUserを取得
sel_users = User.objects.filter(username__in=sel_fds)
# Userのリストに含まれるユーザーが登録したFriendを取得
fds = Friend.objects.filter(owner=request.user) \
.filter(user__in=sel_users)
# すべてのFriendにGroupを設定し保存する
vlist = []
for item in fds:
item.group = group_obj
item.save()
vlist.append(item.user.username)
# メッセージを設定
messages.success(request, ' チェックされたFriendを' + \
sel_group + 'に登録しました。')
# フォームの用意
groupsform = GroupSelectForm(request.user, \
{'groups':sel_group})
friendsform = FriendsForm(request.user, \
friends=friends, vals=vlist)
# GETアクセス時の処理
else:
# フォームの用意
groupsform = GroupSelectForm(request.user)
friendsform = FriendsForm(request.user, friends=friends, \
vals=[])
sel_group = '-'
# 共通処理
createform = CreateGroupForm()
params = {
'login_user':request.user,
'groups_form':groupsform,
'friends_form':friendsform,
'create_form':createform,
'group':sel_group,
}
return render(request, 'sns/groups.html', params)
# Friendの追加処理
@login_required(login_url='/admin/login/')
def add(request):
# 追加するUserを取得
add_name = request.GET['name']
add_user = User.objects.filter(username=add_name).first()
# Userが本人だった場合の処理
if add_user == request.user:
messages.info(request, "自分自身をFriendに追加することは\
できません。")
return redirect(to='/sns')
# publicの取得
(public_user, public_group) = get_public()
# add_userのFriendの数を調べる
frd_num = Friend.objects.filter(owner=request.user) \
.filter(user=add_user).count()
# ゼロより大きければ既に登録済み
if frd_num > 0:
messages.info(request, add_user.username + \
' は既に追加されています。')
return redirect(to='/sns')
# ここからFriendの登録処理
frd = Friend()
frd.owner = request.user
frd.user = add_user
frd.group = public_group
frd.save()
# メッセージを設定
messages.success(request, add_user.username + ' を追加しました!\
groupページに移動して、追加したFriendをメンバーに設定して下さい。')
return redirect(to='/sns')
# グループの作成処理
@login_required(login_url='/admin/login/')
def creategroup(request):
# Groupを作り、Userとtitleを設定して保存する
gp = Group()
gp.owner = request.user
gp.title = request.user.username + 'の' + request.POST['group_name']
gp.save()
messages.info(request, '新しいグループを作成しました。')
return redirect(to='/sns/groups')
# メッセージのポスト処理
@login_required(login_url='/admin/login/')
def post(request):
# POST送信の処理
if request.method == 'POST':
# 送信内容の取得
gr_name = request.POST['groups']
content = request.POST['content']
# Groupの取得
group = Group.objects.filter(owner=request.user) \
.filter(title=gr_name).first()
if group == None:
(pub_user, group) = get_public()
# Messageを作成し設定して保存
msg = Message()
msg.owner = request.user
msg.group = group
msg.content = content
msg.save()
# メッセージを設定
messages.success(request, '新しいメッセージを投稿しました!')
return redirect(to='/sns')
# GETアクセス時の処理
else:
form = PostForm(request.user)
# 共通処理
params = {
'login_user':request.user,
'form':form,
}
return render(request, 'sns/post.html', params)
# 投稿をシェアする
@login_required(login_url='/admin/login/')
def share(request, share_id):
# シェアするMessageの取得
share = Message.objects.get(id=share_id)
print(share)
# POST送信時の処理
if request.method == 'POST':
# 送信内容を取得
gr_name = request.POST['groups']
content = request.POST['content']
# Groupの取得
group = Group.objects.filter(owner=request.user) \
.filter(title=gr_name).first()
if group == None:
(pub_user, group) = get_public()
# メッセージを作成し、設定をして保存
msg = Message()
msg.owner = request.user
msg.group = group
msg.content = content
msg.share_id = share.id
msg.save()
share_msg = msg.get_share()
share_msg.share_count += 1
share_msg.save()
# メッセージを設定
messages.success(request, 'メッセージをシェアしました!')
return redirect(to='/sns')
# 共通処理
form = PostForm(request.user)
params = {
'login_user':request.user,
'form':form,
'share':share,
}
return render(request, 'sns/share.html', params)
# goodボタンの処理
@login_required(login_url='/admin/login/')
def good(request, good_id):
# goodするMessageを取得
good_msg = Message.objects.get(id=good_id)
# 自分がメッセージにGoodした数を調べる
is_good = Good.objects.filter(owner=request.user) \
.filter(message=good_msg).count()
# ゼロより大きければ既にgood済み
if is_good > 0:
messages.success(request, '既にメッセージにはGoodしています。')
return redirect(to='/sns')
# Messageのgood_countを1増やす
good_msg.good_count += 1
good_msg.save()
# Goodを作成し、設定して保存
good = Good()
good.owner = request.user
good.message = good_msg
good.save()
# メッセージを設定
messages.success(request, 'メッセージにGoodしました!')
return redirect(to='/sns')
# これ以降は普通の関数==================
# 指定されたグループおよび検索文字によるMessageの取得
def get_your_group_message(owner, glist, page):
page_num = 10 #ページあたりの表示数
# publicの取得
(public_user,public_group) = get_public()
# チェックされたGroupの取得
groups = Group.objects.filter(Q(owner=owner) \
|Q(owner=public_user)).filter(title__in=glist)
# Groupに含まれるFriendの取得
me_friends = Friend.objects.filter(group__in=groups)
# FriendのUserをリストにまとめる
me_users = []
for f in me_friends:
me_users.append(f.user)
# UserリストのUserが作ったGroupの取得
his_groups = Group.objects.filter(owner__in=me_users)
his_friends = Friend.objects.filter(user=owner) \
.filter(group__in=his_groups)
me_groups = []
for hf in his_friends:
me_groups.append(hf.group)
# groupがgroupsに含まれるか、me_groupsに含まれるMessageの取得
messages = Message.objects.filter(Q(group__in=groups) \
|Q(group__in=me_groups))
# ページネーションで指定ページを取得
page_item = Paginator(messages, page_num)
return page_item.get_page(page)
# publicなUserとGroupを取得する
def get_public():
public_user = User.objects.filter(username='public').first()
public_group = Group.objects.filter \
(owner=public_user).first()
return (public_user, public_group)
templatesを作成
mysite2/sns/templates/snsディレクトリを作成、 layout.html,index.html,groups.html,post.html,share.htmlを作成mysite2/sns/templates/sns/layout.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
crossorigin="anonymous">
</head>
<body class="container">
<nav class="navbar navbar-expand navbar-light bg-light">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="{% url 'index' %}">top</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'post' %}">post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'groups' %}">group</a>
</li>
</ul>
<span>logined: <span class="h6">"{{login_user}}".</span></span>
</nav>
<div>{% block header %}
{% endblock %}</div>
<div class="content">{% block content %}
{% endblock %}</div>
<hr>
<div class="my-3">
<span class="font-weight-bold">
<a href="/admin/logout?next=/sns/">
[ logout ]</a></span>
<span class="float-right">copyright 2020
SYODA-Tuyano.</span>
</div>
</body>
</html>
mysite2/sns/templates/sns/index.html
{% extends 'sns/layout.html' %}
{% block title %}Index{% endblock %}
{% block header %}
<script>
function sendGroupForm(page) {
document.group_form.action += page;
document.group_form.submit();
}
</script>
<h1 class="display-4 text-primary">SNS</h1>
<p>※グループのチェックをONにしてupdateすると、
そのグループに登録されている利用者のメッセージだけが表示されます。</p>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %}
class="{{ message.tags }}"
{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% block content %}
<hr>
<div>
<form action="{% url 'index' %}" method="post" name="group_form">
{% csrf_token %}
{{check_form}}
<div>
<button class="btn btn-primary">update</button>
</div>
</form>
</div>
<table class="table mt-3">
<tr><th>Messages</th></tr>
{% for item in contents %}
<tr><td>
<p class="my-0">
{% if item.group.title == 'public' %}
<span class="bg-info text-light px-1">Public</span>
{% endif %}
{{item.content}}</p>
<p class=""> ({{item.pub_date}})</p>
{% if item.share_id > 0 %}
<ul><li class="text-black-50">"{{item.get_share}}"</li></ul>
{% endif %}
<span class="float-left text-info">
share={{item.share_count}} good={{item.good_count}}
</span>
<span class="float-right">
"{{item.owner}}"(<a href="{% url 'add' %}?name={{item.owner}}">
add friend</a>)
<a href="{% url 'share' item.id %}">
<button class="py-0">share</button></a>
<a href="{% url 'good' item.id %}">
<button class="py-0">good!</button></a>
</span>
</td></tr>
{% endfor %}
</table>
<ul class="pagination justify-content-center">
{% if contents.has_previous %}
<li class="page-item">
<a class="page-link" href="javascript:sendGroupForm(1);">
« first</a>
</li>
<li class="page-item">
<a class="page-link"
href="javascript:sendGroupForm({{contents.previous_page_number}});">
« prev</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link">« first</a>
</li>
<li class="page-item">
<a class="page-link">« prev</a>
</li>
{% endif %}
<li class="page-item">
<a class="page-link">
{{contents.number}}/{{contents.paginator.num_pages}}</a>
</li>
{% if contents.has_next %}
<li class="page-item">
<a class="page-link"
href="javascript:sendGroupForm({{contents.next_page_number }});">
next »</a>
</li>
<li class="page-item">
<a class="page-link"
href="javascript:sendGroupForm({{contents.paginator.num_pages}});">
last »</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link">next »</a>
</li>
<li class="page-item">
<a class="page-link">last »</a>
</li>
{% endif %}
</ul>
{% endblock %}
mysite2/sns/templates/sns/groups.html
{% extends 'sns/layout.html' %}
{% block title %}Groups{% endblock %}
{% block header %}
<h1 class="display-4 text-primary">Group</h1>
<p class="caption">※グループを選択してselect memberすると、
そのグループに登録されている利用者がONになります。
利用者のチェックをONにしてset memberすると、ONにしてある
利用者がグループに追加されます。</p>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"
{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% block content %}
<form action="{% url 'groups' %}" method="post">
{% csrf_token %}
<input type="hidden" name="mode" value="__groups_form__">
{{groups_form}}
<button class="btn btn-primary mt-1">select members</button>
</form>
<hr>
<form action="{% url 'groups' %}" method="post">
{% csrf_token %}
<input type="hidden" name="mode" value="__friends_form__">
<input type="hidden" name="group" value="{{group}}">
{{friends_form}}
<button class="btn btn-primary mt-0">set members</button>
</form>
<hr>
<p>※新しいGroupの登録</p>
<form action="{% url 'creategroup' %}" method="post">
{% csrf_token %}
{{create_form}}
<button class="btn btn-primary mt-1">create new group</button>
</form>
{% endblock %}
mysite2/sns/templates/sns/post.html
{% extends 'sns/layout.html' %}
{% block title %}Post{% endblock %}
{% block header %}
<h1 class="display-4 text-primary">Post</h1>
<p class="caption">※投稿先のグループを選択し、
メッセージを投稿します。</p>
{% if messages %}
<ul class="list-group">
{% for message in messages %}
<li{% if message.tags %} class="list-group-item {{ message.tags }}"
{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% block content %}
<form action="{% url 'post' %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button class="btn btn-primary">Post!</button>
</form>
{% endblock %}
mysite2/sns/templates/sns/share.html
{% extends 'sns/layout.html' %}
{% block title %}Share{% endblock %}
{% block header %}
<h1 class="display-4 text-primary">Share</h1>
<p class="caption">※投稿先のグループを選択し、
下のメッセージをシェアします。</p>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"
{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% block content %}
<p class="bg-light p-3">
"{{share.content}} ({{share.owner}})"</p>
<form action="{% url 'share' share.id %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button class="btn btn-primary mt-2">Share!</button>
</form>
{% endblock %}
Webタブの Reload:をしてから、
https://****.pythonanywhere.com/sns/ にアクセス、