pythonのフィールドエラー
python、djangoの初心者で、参考書を参考し、SNSアプリを写経しているのですが
Cannot resolve keyword 'groups' into field.
というエラーに行き詰っています。
anaconda。windows10を使用しています。
だれか心優しい方助けていただけないでしょうか。
エラーコード
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/sns/
Django Version: 2.2.5
Python Version: 3.7.4
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'sns']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\tumek\Desktop\django_app\sns\views.py" in index
65. messages = get_your_group_message(request.user,glist,None)
File "C:\Users\tumek\Desktop\django_app\sns\views.py" in get_your_group_message
299. |Q(groups__in=me_groups))[:100]
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\query.py" in filter
892. return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\query.py" in _filter_or_exclude
910. clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in add_q
1290. clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in _add_q
1312. current_negated, allow_joins, split_subq, simple_col)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in _add_q
1318. split_subq=split_subq, simple_col=simple_col,
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in build_filter
1190. lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in solve_lookup_type
1049. _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
File "C:\Users\tumek\Anaconda3\envs\myspace\lib\site-packages\django\db\models\sql\query.py" in names_to_path
1420. "Choices are: %s" % (name, ", ".join(available)))
Exception Type: FieldError at /sns/
Exception Value: Cannot resolve keyword 'groups' into field. Choices are: content, good, good_count, group, group_id, id, owner, owner_id, pub_date, share_count, share_id
ソースコード
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']
#検索フォーム
class SearchForm(forms.Form):
search = forms.CharField(max_length=100)
#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)],
)
#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)
#投稿フォーム
class PostForm(forms.Form):
content = forms.CharField(max_length=500, \
widget = forms.Textarea)
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])],
)
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.models import Message,Friend,Group,Good
from.forms import GroupCheckForm,GroupSelectForm, \
SearchForm,FriendsForm,CreateGroupForm,PostForm
from django.db.models import Q
from django.contrib.auth.decorators import login_required
#indexのview関数
@login_required(login_url='/admin/login/')
def index(request):
#publicのuserを取得
(public_user, public_group)=get_public()
#PoST送信時の処理
if request.method == 'POST':
#Groupsのチェックを更新した時の処理
if request.POST['mode'] == '__check_form__':
#フォームの用意
searchform = SearchForm()
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, None)
#Groupsメニューを変更したときの処理
if request.POST['mode'] == '__search_form__':
# フォームの用意
searchform = SearchForm(request.POST)
checkform = GroupCheckForm(request.user)
#Groupのリストを取得
gps = Group.objects.filter(owner=request.user)
glist = [public_group]
for item in gps:
glist.append(item)
#メッセージを取得
message = get_your_group_message(request.user, glist, \
request.POST['search'])
#GETアクセス時の処理
else:
#フォームの用意
searchform = SearchForm()
checkform = GroupCheckForm(request.user)
#Groupのリストを取得
gps =Group.objects.filter(owner=request.user)
glist = [public_group]
for item in gps:
glist.append(item)
#メッセージの取得
messages = get_your_group_message(request.user,glist,None)
#共通処理
params = {
'login_user':request.user,
'contents':messages,
'check_form':checkform,
'search_form':searchform,
}
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':
#Groupメニュー選択肢の処理
if request.POST['mode'] == '__groups_form__':
#選択したGroup名を取得
sel_group = request.POST['groups']
#Groupを取得
gp = Group.objests.filter(owner=request.user) \
.filter(title=sel_group).first()
#Groupに含まれるFriendsを取得
fds = Friend.objects.filter(owner=request.user) \
.filter(group=gp)
#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()
#チェックしたFriendsを取得
sel_fds = request.POST.getlist('friends')
#FriendsのUserを取得
sel_users = User.objects.filter(username__in=sel_fds)
#Userのリストに含まれるユーザーが登録したFriendsを取得
fds = Friends.objects.filter(owner.request.user) \
.filter(user__in=sel_users)
#すべてのFriendsに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')
# ここからFriendの登録処理
frd = Friend()
frd.owner = request.user
frd.user = add_user
frd.group = public_group
frd.save()
# メッセージを設定
message.success(request, add_user.username +'を追加しました \
group ページに移動して、追加したfriendをメンバーに設定して下さい')
return redirect(to='/sns')
#グループの作成処理
@login_required(login_url='/admin/login/')
def creategroup(request):
#gorupを作り、userとtitleを設定して保存する
gp =Group()
gp.owner = request.user
gp.title = request.POST['group_name']
gp.save()
messages.info(requset,'新しいグループを作成しました')
return redirect(to='/sns/groups')
#メッセージのポスト処理
@login_required(login_url='/admin/login/')
def post(requset):
#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):
#shareするmessageの取得
share = Message.objects.get(id=share_id)
#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.succces(request,'すでにメッセージにgoodしています')
return redirect(to='sns/')
#messaseの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/')
#これ以降はview関数ではなく普通の関数==================================
#指定されたグループおよび検索文字によるmessageの取得
def get_your_group_message(owner, glist, find):
#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)
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の取得
if find == None:
messages = Message.objects.filter(Q(group__in=groups) \
|Q(groups__in=me_groups))[:100]
else:
messages = Message.objects.filter(Q(group__in=groups) \
|Q(groups__in=me_groups)).filter(content__contains=find)[:100]
return messages
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)