質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

1回答

1581閲覧

Django:フォローしているユーザーの一覧表示しクリックでそのユーザーとのDM画面に遷移するようにしたい

beginner_19

総合スコア0

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2021/05/27 16:50

編集2021/06/02 13:11

#フォローしているユーザーをDMのトップ画面に設定しそのページに遷移するようにしたい。
現在Djangoでアプリ制作を行なっております。そこでDM機能の実装を行いました。
DM機能は上手く動くもののurlで自分以外のユーザーを指定するとエラーになってしまいます。
そこでDM機能にトップページを実装しフォローしているユーザーの一覧とユーザーをクリックした際にそのユーザーとのDM画面に遷移するような仕組みを作りたいと考えております。
複雑な構造ではございますがご教授頂きたいです。

##該当のコード

ディレクトリ
ディレクトリ

views.py(下記のDmListViewが機能しておりません)

python

1class ChannelFormMixin(FormMixin): 2 form_class = ChannelMessageForm 3 4 # success_url = './' 5 def get_success_url(self): 6 return self.request.path 7 8 # handle the form with this mixin 9 def post(self, request, *args, **kwargs): 10 if not request.user.is_authenticated: 11 raise PermissionDenied 12 form = self.get_form() 13 if form.is_valid(): 14 channel = self.get_object() 15 user = self.request.user 16 content = form.cleaned_data.get("content") 17 channel_obj = ChannelMessage.objects.create(channel=channel, user=user, content=content) 18 if request.is_ajax(): 19 # Django Rest Framework 20 return JsonResponse({"content": channel_obj.content, "username": channel_obj.user.username}, status=201) 21 return super().form_valid(form) 22 else: 23 if request.is_ajax(): 24 return JsonResponse({"errors": form.errors}, status=400) 25 return super().form_invalid(form) 26 27 28class ChannelDetailView(LoginRequiredMixin, ChannelFormMixin, DetailView): 29 template_name = 'private_message.html' 30 queryset = Channel.objects.all() 31 32 def get_context_data(self, *args, **kwargs): 33 context = super().get_context_data(*args, **kwargs) 34 obj = context['object'] 35 # if self.request.user not in obj.users.all(): 36 # raise PermissionDenied 37 context['is_channel_member'] = self.request.user in obj.users.all() 38 return context 39 40 # def get_queryset(self): 41 # user = self.request.user # definitely a user 42 # username = user.username 43 # qs = Channel.objects.all().filter_by_username(username) 44 # return qs 45 46 47class PrivateMessageDetailView(LoginRequiredMixin, ChannelFormMixin, DetailView): 48 template_name = 'dm/private_message.html' 49 50 # def get_template_names(self, *args, **kwargs): 51 # return ['dm/private_message.html'] 52 def get_object(self, *args, **kwargs): 53 username = self.kwargs.get("username") 54 my_username = self.request.user.username 55 if username == my_username: 56 my_channel_obj, _ = Channel.objects.get_or_create_current_user_private_message(self.request.user) 57 return my_channel_obj 58 channel_obj, _ = Channel.objects.get_or_create_private_message(my_username, username) 59 if channel_obj == None: 60 raise Http404 61 return channel_obj 62 63 64def private_message_view(request, username, *args, **kwargs): 65 if not request.user.is_authenticated: 66 return HttpResponse("Nope..") 67 my_username = request.user.username 68 channel_obj, created = Channel.objects.get_or_create_private_message(my_username, username) 69 if created: 70 print("yes it was") 71 channel_users = channel_obj.channeluser_set.all().values("user__username") 72 print(channel_users) 73 channel_messages = channel_obj.channelmessage_set.all() 74 print(channel_messages.values("content")) 75 return HttpResponse(f"channel items - {channel_obj.id}") 76 77 78# フォロー一覧 79class DmListView(LoginRequiredMixin, generic.ListView): 80 model = Connection 81 template_name = 'dm/dm_list.html' 82 context_object_name = 'users' 83 84 def get_queryset(self, **kwargs): 85 username = self.kwargs.get("username") 86 return Connection.objects.filter(follower__username=username)

urls.py

python

1app_name = 'dm' 2 3UUID_CHANNEL_REGEX = r'channel/(?P<pk>[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12})' 4 5urlpatterns = [ 6 path('', views.DmListView.as_view(), name='dm'), 7 re_path(UUID_CHANNEL_REGEX, views.ChannelDetailView.as_view()), 8 path("<str:username>/", views.PrivateMessageDetailView.as_view()), 9]

models.py

python

1User = settings.AUTH_USER_MODEL 2 3 4# Create your models here. 5class BaseModel(models.Model): 6 # 1, 2, 3, 4, 5, 6 7 id = models.UUIDField(default=uuid.uuid4, primary_key=True, db_index=True, editable=False) 8 timestamp = models.DateTimeField(auto_now_add=True) 9 updated = models.DateTimeField(auto_now=True) 10 11 # foreignkey 12 # textfield 13 14 class Meta: 15 abstract = True 16 17 18class ChannelMessage(BaseModel): 19 channel = models.ForeignKey("Channel", null=True, on_delete=models.SET_NULL) 20 user = models.ForeignKey(User, on_delete=models.CASCADE) 21 content = models.TextField() 22 23 24class ChannelUser(BaseModel): 25 channel = models.ForeignKey("Channel", on_delete=models.CASCADE) 26 user = models.ForeignKey(User, on_delete=models.CASCADE) 27 # permissions? 28 29 30# jon_snow -> ned_stark 31# ned_stark -> jon_snow 32 33# oursite.com/dm/jon_snow 34# oursite.com/dm/ned_stark 35 36class ChannelQuerySet(models.QuerySet): 37 def only_one(self): 38 return self.annotate(num_users=Count("users")).filter(num_users=1) 39 40 def only_two(self): 41 return self.annotate(num_users=Count("users")).filter(num_users=2) 42 43 def filter_by_username(self, username): 44 return self.filter(channeluser__user__username=username) 45 46 47class ChannelManager(models.Manager): 48 def get_queryset(self, *args, **kwargs): 49 return ChannelQuerySet(self.model, using=self._db) 50 51 def filter_by_private_message(self, username_a, username_b): 52 return self.get_queryset().only_two().filter_by_username(username_a).filter_by_username(username_b).order_by( 53 "timestamp") 54 55 def get_or_create_current_user_private_message(self, user): 56 qs = self.get_queryset().only_one().filter_by_username(user.username) 57 if qs.exists(): 58 return qs.order_by("timestamp").first(), False 59 channel_obj = Channel.objects.create() 60 ChannelUser.objects.create(user=user, channel=channel_obj) 61 return channel_obj, True 62 63 def get_or_create_private_message(self, username_a, username_b): 64 qs = self.filter_by_private_message(username_a, username_b) 65 if qs.exists(): 66 return qs.order_by("timestamp").first(), False # obj, created 67 User = apps.get_model("auth", model_name='User') 68 user_a, user_b = None, None 69 try: 70 user_a = User.objects.get(username=username_a) 71 except User.DoesNotExist: 72 return None, False 73 try: 74 user_b = User.objects.get(username=username_b) 75 except User.DoesNotExist: 76 return None, False 77 if user_a == None or user_b == None: 78 return None, False 79 channel_obj = Channel.objects.create() 80 ch_u_a = ChannelUser(user=user_a, channel=channel_obj) 81 ch_u_b = ChannelUser(user=user_b, channel=channel_obj) 82 ChannelUser.objects.bulk_create([ch_u_a, ch_u_b]) 83 return channel_obj, True 84 85 86class Channel(BaseModel): # models.model 87 # slack-like 88 # 1 user 89 # 2 users 90 # 2+ users 91 users = models.ManyToManyField(User, blank=True, through=ChannelUser) 92 # channel_type 93 # max_users 94 # status -> private, public 95 # slug -> Lookup slug 96 # title -> Channel name/title 97 98 objects = ChannelManager() 99 100 class Meta: 101 ordering = ['timestamp'] 102

dm_list.html

html

1{% block content %} 2 3<div class="col-6 tweet"> 4 <h1>DM</h1> 5 {% for user in users %} 6 <h3><a href="">{{ user.following.username }}</a></h3> 7 {% endfor %} 8 <a href="{% url 'app:tweet_list' %}"> 9 <button type="button" class="btn btn-lg btn-secondary mt-5">戻る<i class="fas fa-backward"></i></button> 10 </a> 11</div> 12 13{% endblock %}

private_message.html

python

1{% block content %} 2 3</style> 4 5<div class="col-6"> 6 Channel - {{ object.id }} 7 <h1>DM機能</h1> 8 9 <div id='message-container'> 10 {% for message in object.channelmessage_set.all %} 11 <div class='my-3 w-35 px-1 rounded {% if request.user == message.user %}mr-0 bg-primary text-white {% else %}bg-secondary ml-0{% endif %}'> 12 <b>{{ message.user.username }}</b> 13 14 <p>{{ message.content }}</p> 15 </div> 16 {% endfor %} 17 </div> 18 19 20 <h1>Channel Users</h1> 21 {% for channel_user in object.channeluser_set.all %} 22 <div> 23 {{ channel_user.user.username }} {% if request.user == channel_user.user %}this is you {% endif %} 24 </div> 25 26 {% endfor %} 27 28 <form id='message-form' action="{{ request.path }}" method='POST'> {% csrf_token %} 29 {{ form.as_p }} 30 <input id="content" type='submit' value='Message'/> 31 </form> 32</div> 33 34 35{% endblock %}

####自分以外のユーザーを指定した際に発生するエラー
Exception Type: AttributeError
Exception Value:Manager isn't available; 'auth.User' has been swapped for 'accounts.MyUser'

###試したこと
フォローユーザーの一覧を作成すべく、DmListViewを作成しましたが、機能しませんでした。ただエラーは出ておりません。


ここまで読んで下さりありがとう。
複雑な質問で申し訳ありません。
解決方法をご教授頂ければ幸いです。


####追記
view

python

1class DmListView(LoginRequiredMixin, generic.ListView): 2 model = Connection 3 template_name = 'dm/dm_list.html' 4 context_object_name = 'users' 5 6 def get_queryset(self, **kwargs): 7 username = self.kwargs['username'] 8 return Connection.objects.filter(follower__username=username)

エラー内容
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

どちらかが原因だと思います

  • auth.Userを使用すべきところでaccounts.MyUserを使用している
  • accounts.MyUserを使用すべきところでauth.Userを使用している

投稿2021/05/28 02:16

tatamyiwathy

総合スコア1045

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beginner_19

2021/06/01 15:15

コメントありがとうございます。頂いた回答をもとにget_querysetにてself.kwargs['username']やMyUserにfilterをかけたりしましたがusernameを取得できませんでした。KeyError:usenameとなるのですがusernameが取得できない状況です。もし何かわかることがあればご教授頂きたく思います。よろしくお願い致します。
tatamyiwathy

2021/06/02 11:14

エラー表示は提示されているものだけでしょうか。 前後に表示されているものはありませんでしたでしょうか。
beginner_19

2021/06/02 13:09

コメントありがとうございます。現在はviewで def get_queryset(self, **kwargs): username = self.kwargs['username'] return Connection.objects.filter(follower__username=username) と指定しております。エラー内容の画像をアップ質問下部にアップしております。よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問